• Linux TCP 通信并发


    多进程

    客户端

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. int main() {
    7. //创建套接字
    8. int lfd = socket(AF_INET, SOCK_STREAM, 0);
    9. if(lfd == -1) {
    10. perror("socket");
    11. exit(-1);
    12. }
    13. //连接服务器
    14. struct sockaddr_in serveraddr;
    15. inet_pton(AF_INET, "192.168.245.129", &serveraddr.sin_addr.s_addr);
    16. serveraddr.sin_family = AF_INET;
    17. serveraddr.sin_port = htons(9999);
    18. int ret = connect(lfd, (struct sockaddr *) &serveraddr, sizeof(serveraddr));
    19. if(ret == -1) {
    20. perror("connect");
    21. _exit(-1);
    22. }
    23. //通信
    24. int i = 0;
    25. char receiveBuf[1024] = {0};
    26. while(1) {
    27. sprintf(receiveBuf, "data: %d\n", i++);
    28. write(lfd, receiveBuf, strlen(receiveBuf));
    29. sleep(1);
    30. int len = read(lfd, receiveBuf, sizeof(receiveBuf));
    31. if(len == -1) {
    32. perror("read");
    33. exit(0);
    34. } else if(len > 0) {
    35. printf("receive server data: %s\n", receiveBuf);
    36. } else if (len == 0) {
    37. printf("server closed...");
    38. }
    39. }
    40. close(lfd);
    41. }

    服务器

    1. #define _XOPEN_SOURCE
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. void recyleChild(int arg) {
    11. while(1) {
    12. int ret = waitpid(-1, NULL, WNOHANG);
    13. if(ret == -1) {
    14. break;
    15. } else if (ret == 0) {
    16. break;
    17. } else if (ret > 0) {
    18. printf("pid %d is resaved\n", ret);
    19. }
    20. }
    21. }
    22. int main() {
    23. //注册信号捕捉函数
    24. struct sigaction act;
    25. act.sa_flags = 0;
    26. sigemptyset(&act.sa_mask);
    27. act.sa_handler = recyleChild;
    28. sigaction(SIGCHLD, &act, NULL);
    29. //创建socket
    30. int lfd = socket(AF_INET, SOCK_STREAM, 0);
    31. if(lfd == -1) {
    32. perror("socket");
    33. exit(0);
    34. }
    35. struct sockaddr_in saddr;
    36. saddr.sin_family = AF_INET;
    37. saddr.sin_port = htons(9999);
    38. saddr.sin_addr.s_addr = INADDR_ANY;
    39. //绑定
    40. int ret = bind(lfd, (struct sockaddr*)&saddr, sizeof(saddr));
    41. if(ret == -1) {
    42. perror("bind");
    43. exit(0);
    44. }
    45. //监听
    46. ret = listen(lfd, 128);
    47. if(ret == -1) {
    48. perror("listen");
    49. exit(0);
    50. }
    51. //接受链接
    52. while(1) {
    53. struct sockaddr_in cliaddr;
    54. int len = sizeof(cliaddr);
    55. int cfd = accept(lfd, (struct sockaddr*)&cliaddr, &len);
    56. if(cfd == -1) {
    57. if(errno == EINTR) {
    58. continue;
    59. }
    60. perror("accept");
    61. exit(-1);
    62. }
    63. //每连接一个,创建一个子进程
    64. pid_t pid = fork();
    65. if(pid == 0) {
    66. char clientIP[16];
    67. inet_ntop(AF_INET, &cliaddr.sin_addr.s_addr, clientIP, 16);
    68. unsigned short cliPort = ntohs(cliaddr.sin_port);
    69. printf("Client Port is %d, client addr is %s\n", cliPort, clientIP);
    70. char recvBuf[1024] = {0};
    71. while(1) {
    72. int len = read(cfd, &recvBuf, sizeof(recvBuf));
    73. if(len == -1) {
    74. perror("read");
    75. return 0;
    76. } else if(len > 0) {
    77. printf("recv client data : %s \n", recvBuf);
    78. } else {
    79. printf("closed.....");
    80. }
    81. write(cfd, &recvBuf, sizeof(recvBuf));
    82. }
    83. close(cfd);
    84. exit(0);
    85. }
    86. }
    87. close(lfd);
    88. return 0;
    89. }

    多线程

    服务器

    1. #define _XOPEN_SOURCE
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. struct sockinfo {
    10. int fd;
    11. struct sockaddr_in saddr;
    12. pthread_t tid;
    13. };
    14. struct sockinfo sockinfos[128];
    15. void* working(void* arg) {
    16. struct sockinfo* pinfo = (struct sockinfo*) arg;
    17. char clientIP[16];
    18. inet_ntop(AF_INET, &pinfo->saddr.sin_addr.s_addr, clientIP, 16);
    19. unsigned short cliPort = ntohs(pinfo->saddr.sin_port);
    20. printf("Client Port is %d, client addr is %s\n", cliPort, clientIP);
    21. char recvBuf[1024] = {0};
    22. while(1) {
    23. int len = read(pinfo->fd, &recvBuf, sizeof(recvBuf));
    24. if(len == -1) {
    25. perror("read");
    26. return 0;
    27. } else if(len > 0) {
    28. printf("recv client data : %s \n", recvBuf);
    29. } else {
    30. printf("closed.....");
    31. }
    32. write(pinfo->fd, &recvBuf, sizeof(recvBuf));
    33. }
    34. close(pinfo->fd);
    35. exit(0);
    36. return NULL;
    37. }
    38. int main() {
    39. //创建socket
    40. int lfd = socket(AF_INET, SOCK_STREAM, 0);
    41. if(lfd == -1) {
    42. perror("socket");
    43. exit(0);
    44. }
    45. struct sockaddr_in saddr;
    46. saddr.sin_family = AF_INET;
    47. saddr.sin_port = htons(9999);
    48. saddr.sin_addr.s_addr = INADDR_ANY;
    49. //绑定
    50. int ret = bind(lfd, (struct sockaddr*)&saddr, sizeof(saddr));
    51. if(ret == -1) {
    52. perror("bind");
    53. exit(0);
    54. }
    55. //监听
    56. ret = listen(lfd, 128);
    57. if(ret == -1) {
    58. perror("listen");
    59. exit(0);
    60. }
    61. //初始化数据
    62. int max = sizeof(sockinfos) / sizeof(sockinfos[0]);
    63. for(int i = 0; i < max; i++) {
    64. memset(&sockinfos[i], 0, sizeof(sockinfos[i]));
    65. sockinfos[i].fd = -1;
    66. sockinfos[i].tid = -1;
    67. }
    68. //接受链接
    69. while(1) {
    70. struct sockaddr_in cliaddr;
    71. int len = sizeof(cliaddr);
    72. int cfd = accept(lfd, (struct sockaddr*)&cliaddr, &len);
    73. if(cfd == -1) {
    74. perror("accept");
    75. exit(-1);
    76. }
    77. struct sockinfo * pinfo;
    78. for(int i = 0; i < max; i++) {
    79. if(sockinfos[i].fd == -1) {
    80. pinfo = &sockinfos[i];
    81. break;
    82. }
    83. if(i == max - 1) {
    84. sleep(1);
    85. i--;
    86. }
    87. }
    88. pinfo->fd = cfd;
    89. memcpy(&pinfo->saddr, &cliaddr, len);
    90. //每连接一个,创建一个子进程
    91. pthread_create(&pinfo->tid, NULL, working, pinfo);
    92. pthread_detach(pinfo->tid);
    93. }
    94. close(lfd);
    95. return 0;
    96. }

    客户端

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. int main() {
    7. //创建套接字
    8. int lfd = socket(AF_INET, SOCK_STREAM, 0);
    9. if(lfd == -1) {
    10. perror("socket");
    11. exit(-1);
    12. }
    13. //连接服务器
    14. struct sockaddr_in serveraddr;
    15. inet_pton(AF_INET, "192.168.245.129", &serveraddr.sin_addr.s_addr);
    16. serveraddr.sin_family = AF_INET;
    17. serveraddr.sin_port = htons(9999);
    18. int ret = connect(lfd, (struct sockaddr *) &serveraddr, sizeof(serveraddr));
    19. if(ret == -1) {
    20. perror("connect");
    21. _exit(-1);
    22. }
    23. //通信
    24. int i = 0;
    25. char receiveBuf[1024] = {0};
    26. while(1) {
    27. sprintf(receiveBuf, "data: %d\n", i++);
    28. write(lfd, receiveBuf, strlen(receiveBuf));
    29. sleep(1);
    30. int len = read(lfd, receiveBuf, sizeof(receiveBuf));
    31. if(len == -1) {
    32. perror("read");
    33. exit(0);
    34. } else if(len > 0) {
    35. printf("receive server data: %s\n", receiveBuf);
    36. } else if (len == 0) {
    37. printf("server closed...");
    38. }
    39. }
    40. close(lfd);
    41. }

  • 相关阅读:
    数据结构·栈与队列介绍与实现
    CCLink转Modbus TCP网关_MODBUS网口设置
    220V交流转直流的简易电源设计
    关于网络流
    react项目实现语音识别功能
    python、pyqt5实现人脸检测、性别和年龄预测
    遍历数组的10个高阶函数
    GAMES101 作业0 环境配置 超详细小白教程
    DDL、DML
    css3d制作正方体
  • 原文地址:https://blog.csdn.net/weixin_44273624/article/details/133649075