一、服务器程序(server.c) 

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <sys/socket.h>
  6. #include <sys/select.h>
  7. #include <netinet/in.h>
  8. #include <strings.h>
  9.  
  10. #define SERV_PORT 9999
  11. #define MAXLINE 4096
  12.  
  13. #define SA struct sockaddr
  14.  
  15. int max(int, int);
  16. void proSession(FILE*, int, const struct sockaddr*);
  17. ssize_t writen(int, const void*, size_t);
  18. char *sock_ntop(const struct sockaddr*, socklen_t);
  19.  
  20. int main(int argc, char *argv[]) {
  21. int listenfd, connfd;
  22. pid_t childpid;
  23. socklen_t clilen;
  24. struct sockaddr_in servaddr;
  25. struct sockaddr_in cliaddr;
  26.  
  27. listenfd = socket(AF_INET, SOCK_STREAM, );
  28.  
  29. bzero(&servaddr, sizeof(servaddr));
  30. servaddr.sin_family = AF_INET;
  31. servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
  32. servaddr.sin_port = htons(SERV_PORT);
  33.  
  34. bind(listenfd, (SA *)&servaddr, sizeof(servaddr)); /* 将套接字和套接字地址结构绑定 */
  35.  
  36. listen(listenfd, ); /* 将套接字转换为监听套接字 */
  37.  
  38. clilen = sizeof(cliaddr);
  39. if ( (connfd = accept(listenfd, (SA *)&cliaddr, &clilen)) > ) {
  40. proSession(stdin, connfd, (SA *)&cliaddr); /* 处理会话 */
  41. }
  42. exit(0);
  43. }
  44.  
  45. void proSession(FILE *fp, int sockfd, const struct sockaddr *addr) {
  46. int maxfdp1, stdineof;
  47. fd_set rset;
  48. char buf[MAXLINE];
  49. int n;
  50.  
  51. stdineof = ;
  52. FD_ZERO(&rset);
  53. for ( ; ; ) {
  54. if (stdineof == ) {
  55. FD_SET(fileno(fp), &rset);
  56. }
  57. FD_SET(sockfd, &rset);
  58. maxfdp1 = max(fileno(fp), sockfd) + ;
  59. select(maxfdp1, &rset, NULL, NULL, NULL);
  60.  
  61. if (FD_ISSET(sockfd, &rset)) { /* 套接字描述符就绪 */
  62. if ( (n = read(sockfd, buf, MAXLINE)) == ) {
  63. if (stdineof == ) {
  64. return;
  65. } else {
  66. exit(0);
  67. }
  68. }
  69. printf("%s\n", sock_ntop(addr, sizeof(addr)));
  70. write(fileno(stdout), buf, n);
  71. printf("\n");
  72. }
  73. if (FD_ISSET(fileno(fp), &rset)) { /* 输入描述符就绪 */
  74. if ( (n = read(fileno(fp), buf, MAXLINE)) == ) {
  75. stdineof = ;
  76. shutdown(sockfd, SHUT_WR); /* 发送 FIN */
  77. FD_CLR(fileno(fp), &rset);
  78. continue;
  79. }
  80. writen(sockfd, buf, n);
  81. }
  82. }
  83. }
  84.  
  85. int max(int numberone, int numbertwo) {
  86. return ( (numberone >= numbertwo)?numberone:numbertwo);
  87. }

二、客户端程序(client.c)

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <strings.h>
  4. #include <unistd.h>
  5. #include <arpa/inet.h>
  6. #include <netinet/in.h>
  7. #include <sys/socket.h>
  8.  
  9. #define SA struct sockaddr
  10. #define SERV_PORT 9999
  11. #define MAXLINE 4096
  12.  
  13. int max(int, int);
  14. void proSession(FILE*, int, const struct sockaddr*);
  15. ssize_t writen(int, const void*, size_t);
  16. char *sock_ntop(const struct sockaddr*, socklen_t);
  17.  
  18. int main(int argc, char *argv[]) {
  19. pid_t childpid;
  20. int sockfd;
  21. struct sockaddr_in servaddr;
  22.  
  23. if (argc != ) {
  24. printf("usage: %s <IPaddress>\n", argv[]);
  25. exit(-1);
  26. }
  27.  
  28. sockfd = socket(AF_INET, SOCK_STREAM, );
  29.  
  30. bzero(&servaddr, sizeof(servaddr));
  31. servaddr.sin_family = AF_INET;
  32. servaddr.sin_port = htons(SERV_PORT);
  33. inet_pton(AF_INET, argv[], &servaddr.sin_addr);
  34.  
  35. if (connect(sockfd, (SA *)&servaddr, sizeof(servaddr)) == ) {
  36. proSession(stdin, sockfd, (SA *)&servaddr); /* 处理会话 */
  37. }
  38.  
  39. exit(0);
  40. }
  41.  
  42. void proSession(FILE *fp, int sockfd, const struct sockaddr* addr) {
  43. int maxfdp1, stdineof;
  44. fd_set rset;
  45. char buf[MAXLINE];
  46. int n;
  47.  
  48. stdineof = ;
  49. FD_ZERO(&rset);
  50. for ( ; ; ) {
  51. if (stdineof == ) {
  52. FD_SET(fileno(fp), &rset);
  53. }
  54. FD_SET(sockfd, &rset);
  55. maxfdp1 = max(fileno(fp), sockfd) + ;
  56. select(maxfdp1, &rset, NULL, NULL, NULL);
  57.  
  58. if (FD_ISSET(sockfd, &rset)) { /* 套接字描述符就绪 */
  59. if ( (n = read(sockfd, buf, MAXLINE)) == ) {
  60. if (stdineof == ) {
  61. return;
  62. } else {
  63. exit(0);
  64. }
  65. }
  66. printf("%s\n", sock_ntop(addr, sizeof(addr)));
  67. write(fileno(stdout), buf, n);
  68. printf("\n");
  69. }
  70. if (FD_ISSET(fileno(fp), &rset)) { /* 输入描述符就绪 */
  71. if ( (n = read(fileno(fp), buf, MAXLINE)) == ) {
  72. stdineof = ;
  73. shutdown(sockfd, SHUT_WR); /* 发送 FIN */
  74. FD_CLR(fileno(fp), &rset);
  75. continue;
  76. }
  77. writen(sockfd, buf, n);
  78. }
  79. }
  80. }
  81.  
  82. int max(int numberone, int numbertwo) {
  83. return ( (numberone >= numbertwo)?numberone:numbertwo);
  84. }

三、服务器程序或客户端程序用到的程序

 (1)sock_ntop.c

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <netinet/in.h>
  5. #include <sys/un.h>
  6. #include <arpa/inet.h>
  7. #include <sys/socket.h>
  8.  
  9. char *sock_ntop(const struct sockaddr *sa, socklen_t salen) {
  10.  
  11. char portstr[];
  12. static char str[];
  13.  
  14. switch (sa->sa_family) {
  15. case AF_INET: {
  16. struct sockaddr_in *sin = (struct sockaddr_in *) sa;
  17.  
  18. if (inet_ntop(AF_INET, &sin->sin_addr, str,
  19. sizeof(str)) == NULL) {
  20. return(NULL);
  21. }
  22. if (ntohs(sin->sin_port) != ) {
  23. snprintf(portstr, sizeof(portstr), ":%d",
  24. ntohs(sin->sin_port));
  25. strcat(str, portstr);
  26. }
  27. return(str);
  28. }
  29. case AF_INET6: {
  30. struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
  31.  
  32. str[] = '[';
  33. if (inet_ntop(AF_INET6, &sin6->sin6_addr, str + ,
  34. sizeof(str) - ) == NULL) {
  35. return(NULL);
  36. }
  37. if (ntohs(sin6->sin6_port) != ) {
  38. snprintf(portstr, sizeof(portstr), "]:%d",
  39. ntohs(sin6->sin6_port));
  40. strcat(str, portstr);
  41. return(str);
  42. }
  43. return (str + );
  44. }
  45. case AF_UNIX: {
  46. struct sockaddr_un *unp = (struct sockaddr_un *) sa;
  47.  
  48. if (unp->sun_path[] == ) {
  49. strcpy(str, "(no pathname bound)");
  50. } else {
  51. snprintf(str, sizeof(str), "%s", unp->sun_path);
  52. }
  53. return(str);
  54. }
  55. default: {
  56. snprintf(str, sizeof(str), "sock_ntop: unknown AF_xxx: %d, len %d",
  57. sa->sa_family, salen);
  58. return(str);
  59. }
  60. }
  61. return (NULL);
  62. }

 (2)writen.c

  1. #include <unistd.h>
  2. #include <errno.h>
  3.  
  4. ssize_t writen(int fd, const void *vptr, size_t n) {
  5. size_t nleft;
  6. ssize_t nwriten;
  7. const char *ptr;
  8.  
  9. ptr = vptr;
  10. nleft = n;
  11. while (nleft > ) {
  12. if ( (nwriten = write(fd, ptr, nleft)) <= ) {
  13. if (nwriten < && errno) {
  14. nwriten = ; /* call write() again */
  15. } else {
  16. return (-); /* error */
  17. }
  18. }
  19. nleft -= nwriten;
  20. ptr += nwriten;
  21. }
  22. return (n - nwriten);
  23. }

四、Makefile文件

 (1)服务器 

  1. target=server
  2. cc=gcc
  3. $(target):writen.o server.o sock_ntop.o
  4. $(cc) sock_ntop.o writen.o server.o -o $(target)
  5. sock_ntop.o:sock_ntop.c
  6. $(cc) -c sock_ntop.c -o sock_ntop.o
  7. writen.o:writen.c
  8. $(cc) -c writen.c -o writen.o
  9. server.o:server.c
  10. $(cc) -c server.c -o server.o
  11. clean:
  12. rm -rf *.o $(target)

 (2)客户端

  1. target=client
  2. cc=gcc
  3. $(target):writen.o client.o sock_ntop.o
  4. $(cc) writen.o client.o sock_ntop.o -o $(target)
  5. writen.o:writen.c
  6. $(cc) -c writen.c -o writen.o
  7. server.o:client.c
  8. $(cc) -c client.c -o client.o
  9. sock_ntop.o:sock_ntop.c
  10. $(cc) -c sock_ntop.c -o sock_ntop.o
  11. clean:
  12. rm -rf *.o $(target)
  13. ~

select实现简单TCP通信(ubuntu 18.04)的更多相关文章

  1. Ubuntu 18.04及Snap体验——让Linux入门更简单(转))

    https://www.linuxidc.com/Linux/2018-06/152993.htm 初次听说过Linux的时候,是大一计算机课时候老师介绍说除了Windows还有Linux.Unix操 ...

  2. Ubuntu 18.04 LTS 常用软件安装杂记

    之前个人笔记本装的是 Linux Mint,用了一段时间但是体验不佳,所以打算换成 Ubuntu .作为一个 Linux 小白,当时配置一些软件环境费了不少时间.这次打算简单记录下,和大家分享一下我的 ...

  3. 基于Ubuntu 18.04.5 LTS 部署Ceph集群测试及Ceph RDB的使用。

    1.ceph简介 Ceph在一个统一的系统中独特地提供对象.块和文件存储 1.1 ceph官网架构图 1.2 架构解释   CEPH 对象存储 CEPH 块设备 CEPH 文件系统 RESTful 接 ...

  4. Ubuntu 18.04下Couldn't connect to Docker daemon at http+docker://localunixsocket解决办法

    一台服务器系统为:Ubuntu 18.04 LTS,上面建了git裸仓库,用于开发吧代码push到这里.同时WEB测试环境通过docker也部署在这台.通过git钩子post-receive,当有新代 ...

  5. Debian 9 / Debian 10 / Ubuntu 18.04 / Ubuntu 18.10快速开启BBR加速 或 关闭BBR加速

    如果使用的是Debian 9.Debian 10.Ubuntu 18.04.Ubuntu 18.10等内核高于4.9版本的系统,均可以使用此方法开启BBR加速,若你使用了Ubuntu 19.04的系统 ...

  6. 如何在Ubuntu 18.04上安装Apache Web服务器

    一. apt库安装 1.在终端输入更新检查命令,sudo apt-get update 2. 在更新完成后(如果不想检查更新,也可直接输入此步)输入:sudo apt-get install apac ...

  7. Ubuntu 18.04.1 LTS + kolla-ansible 部署 openstack Rocky all-in-one 环境

    1. kolla 项目介绍 简介 kolla 的使命是为 openstack 云平台提供生产级别的.开箱即用的自动化部署能力. kolla 要实现 openetack 部署分为两步,第一步是制作 do ...

  8. 在Ubuntu 18.04系统上安装Systemback的方法(抄)

    在Ubuntu 18.04系统上安装Systemback的方法 2018-12-26 21:39:05作者:林莉稿源:云网牛站 本文介绍如何在Ubuntu 18.04或者Ubuntu 18.10系统上 ...

  9. Ubuntu 18.04 系统配置 NPM环境和mysql数据库问题解决

    Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效. 今天我就为大家 使用 Ubun ...

随机推荐

  1. base64加密图片处理

    场景:下载html中内嵌的base64加密图片 举个例子,博客园的插入图片有两种方式,一是引用图片链接,二是直接粘贴2进制图片文件.以第二种方式的图片则是以base64加密的方式内嵌在html页面中. ...

  2. 20165223 结对编程之四则运算week1-阶段性总结

    目录 一.结对对象 二.需求分析 三.设计思路 四.功能截图 五.结对感受 一.结对对象 担任角色 驾驶员(Driver):20165223 蔡霓(是控制键盘输入的人) 领航员(Navigator): ...

  3. Cookie知识点总结

    Cookie机制是采用客户端保持Http状态信息的方案. Cookie是在浏览器访问web服务器的某个资源的时候,由web服务器在http响应消息头中附带给浏览器的一个小文本文件. 一旦web服务器保 ...

  4. 由AC自动机引发的灵感

    一,WA自动机 #include <cstdio> using namespace std; int main() { printf("☺"); ; } 二,TLE自动 ...

  5. A1072. Gas Station

    A gas station has to be built at such a location that the minimum distance between the station and a ...

  6. 收集JavaScript中常用的方法函数

    本文中,收集了一些比较常用的Javascript函数,希望对学习JS的朋友们有所帮助. 1. 字符串长度截取 function cutstr(str, len) { var temp, icount ...

  7. canvas简易画板

    代码展示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  8. iostat 磁盘io分析工具

    一:简介 iostat(I/O statistics)输入输出缩写,用来动态监视系统的磁盘操作活动.它能监视磁盘的活动统计情况,同时也能监视CPU的活动情况.缺点是,iostat不能对某一个具体的进程 ...

  9. 常用的一些cmd命令

    常用的一些cmd命令总结 ----------- 1.ping主机名字,类似于ping机子的IP地址 2.查看当前用户的dos命令 3.查看机器名 调出计算器命令:calc 调出远程桌面的命令:mst ...

  10. golang 热升级

    需求场景 干净利落地升级正在运行的agent程序.适用于Devops团队. 目标: 不关闭现有连接:例如我们不希望关掉已部署的运行中的程序.但又想不受限制地随时升级服务. 新的进程要能够启动并替换掉旧 ...