• 通过多线程并发方式(fork)实现服务器


     与多进程实现对比来看。

    示例来源于网络视频

    1. #include <stdio.h>
    2. #include <string.h>
    3. #include <arpa/inet.h>
    4. #include <pthread.h>
    5. #include <ctype.h>
    6. #include <unistd.h>
    7. #include <fcntl.h>
    8. #include "wrap.h"
    9. #define MAXLINE 8192
    10. #define SERV_PORT 8000
    11. struct s_info { //定义一个结构体, 将地址结构跟cfd捆绑
    12. struct sockaddr_in cliaddr;
    13. int connfd;
    14. };
    15. void *do_work(void *arg)
    16. {
    17. int n,i;
    18. struct s_info *ts = (struct s_info*)arg;
    19. char buf[MAXLINE];
    20. char str[INET_ADDRSTRLEN]; //#define INET_ADDRSTRLEN 16 可用"[+d"查看
    21. while (1) {
    22. n = Read(ts->connfd, buf, MAXLINE); //读客户端
    23. if (n == 0) {
    24. printf("the client %d closed...\n", ts->connfd);
    25. break; //跳出循环,关闭cfd
    26. }
    27. printf("received from %s at PORT %d\n",
    28. inet_ntop(AF_INET, &(*ts).cliaddr.sin_addr, str, sizeof(str)),
    29. ntohs((*ts).cliaddr.sin_port)); //打印客户端信息(IP/PORT)
    30. for (i = 0; i < n; i++)
    31. buf[i] = toupper(buf[i]); //小写-->大写
    32. Write(STDOUT_FILENO, buf, n); //写出至屏幕
    33. Write(ts->connfd, buf, n); //回写给客户端
    34. }
    35. Close(ts->connfd);
    36. return (void *)0;
    37. }
    38. int main(void)
    39. {
    40. struct sockaddr_in servaddr, cliaddr;
    41. socklen_t cliaddr_len;
    42. int listenfd, connfd;
    43. pthread_t tid;
    44. struct s_info ts[256]; //根据最大线程数创建结构体数组.
    45. int i = 0;
    46. listenfd = Socket(AF_INET, SOCK_STREAM, 0); //创建一个socket, 得到lfd
    47. bzero(&servaddr, sizeof(servaddr)); //地址结构清零
    48. servaddr.sin_family = AF_INET;
    49. servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //指定本地任意IP
    50. servaddr.sin_port = htons(SERV_PORT); //指定端口号 8000
    51. Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); //绑定
    52. Listen(listenfd, 128); //设置同一时刻链接服务器上限数
    53. printf("Accepting client connect ...\n");
    54. while (1) {
    55. cliaddr_len = sizeof(cliaddr);
    56. connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len); //阻塞监听客户端链接请求
    57. ts[i].cliaddr = cliaddr;
    58. ts[i].connfd = connfd;
    59. /* 达到线程最大数时,pthread_create出错处理, 增加服务器稳定性 */
    60. pthread_create(&tid, NULL, do_work, (void*)&ts[i]);
    61. pthread_detach(tid); //子线程分离,防止僵线程产生.
    62. i++;
    63. }
    64. return 0;
    65. }

  • 相关阅读:
    FastAdmin 列表多选后批量操作数据
    最新centos7 部署 k8s v1.26,简单易懂,跟着命令敲就完事
    回溯leetcode.1774
    14. SpringBoot项目之数据保存到数据库
    Ionic header content footer toolbar UI实例
    【Ruby】怎样判断一个类是否有某个方法,一个实例是否有某个属性?
    2022牛客多校(三)
    STL容器
    Seata 与三大平台携手编程之夏,百万奖金等你来拿
    最全的 ES 重点内容整理(上)
  • 原文地址:https://blog.csdn.net/modi000/article/details/136359373