• TCp并发服务器


    进程实现TCP并发服务器 

    1. #include <stdio.h>
    2. #include <sys/types.h>
    3. #include <sys/socket.h>
    4. #include <arpa/inet.h>
    5. #include <netinet/in.h>
    6. #include <unistd.h>
    7. #include <string.h>
    8. #include <wait.h>
    9. #include <signal.h>
    10. #include <stdlib.h>
    11. #define ERR_MSG(Msg) do{\
    12. fprintf(stderr,"__%d__:",__LINE__);\
    13. perror(Msg);\
    14. }while(0)
    15. #define IP "192.168.8.10"
    16. #define PORT 6666
    17. typedef void (*sighandler_t)(int);
    18. int recvdata(int newsdpdp,struct sockaddr_in bin);
    19. void handler(int p)
    20. {
    21. while(waitpid(-1, NULL, WNOHANG) > 0);
    22. }
    23. int main(int argc, const char *argv[])
    24. {
    25. sighandler_t s = signal(SIGCHLD, handler);
    26. if(SIG_ERR == s)
    27. {
    28. ERR_MSG("signal");
    29. }
    30. //创建字节流式套接字
    31. int sdp=socket(AF_INET,SOCK_STREAM,0);
    32. if(sdp<0)
    33. {
    34. ERR_MSG("sdp");
    35. return -1;
    36. }
    37. //允许端口被重复使用
    38. int reuse = 1;
    39. if(setsockopt(sdp, SOL_SOCKET, SO_REUSEADDR, &reuse ,sizeof(reuse)) < 0)
    40. {
    41. ERR_MSG("setsockopt");
    42. return -1;
    43. }
    44. printf("允许端口快速重用\n");
    45. //将IP号和端口号绑定在套接字文件描述符
    46. struct sockaddr_in sin;
    47. sin.sin_family=AF_INET;
    48. sin.sin_port=htons(PORT);
    49. sin.sin_addr.s_addr=inet_addr(IP);
    50. socklen_t addrlen=sizeof(sin);
    51. if(bind(sdp,(struct sockaddr *)&sin,addrlen)<0)
    52. {
    53. ERR_MSG("bind");
    54. return -1;
    55. }
    56. printf("绑定成功\n");
    57. //将套接字设置为监听状态
    58. if(listen(sdp,128)<0)
    59. {
    60. ERR_MSG("listen");
    61. }
    62. printf("监听成功\n");
    63. struct sockaddr_in bin;
    64. socklen_t addrlen1=sizeof(bin);
    65. int newsdp=0;
    66. //生成新的文件描述符,存储链接成功的客户信息
    67. while(1)
    68. {
    69. newsdp=accept(sdp,(struct sockaddr *)&bin,&addrlen1);
    70. if(newsdp<0)
    71. {
    72. ERR_MSG("accept");
    73. return -1;
    74. }
    75. printf("对方客户端ip=[%s] port=%d连接成功 ",inet_ntoa(bin.sin_addr),ntohs(bin.sin_port));
    76. pid_t pid;
    77. pid=fork();
    78. if(pid<0)
    79. {
    80. ERR_MSG("fork");
    81. }
    82. if(pid>0)
    83. {
    84. close(newsdp);
    85. }
    86. if(pid==0)
    87. {
    88. close(sdp);
    89. recvdata(newsdp,bin);
    90. exit(0);
    91. }
    92. }
    93. close(sdp);
    94. return 0;
    95. }
    96. int recvdata(int newsdp,struct sockaddr_in bin)
    97. {
    98. //接受数据
    99. char buf[128];
    100. bzero(buf,sizeof(buf));
    101. while(1)
    102. {
    103. ssize_t rcv;
    104. rcv=recv(newsdp,buf,sizeof(buf),0);
    105. if(rcv<0)
    106. {
    107. ERR_MSG("recv");
    108. return -1;
    109. }
    110. if(rcv==0)
    111. {
    112. printf("对方客户端关闭\n");
    113. break;
    114. }
    115. printf("对方客户端ip=[%s] port=%d newsdp=%d读取到的数据为%s\n",inet_ntoa(bin.sin_addr),ntohs(bin.sin_port),newsdp,buf);
    116. //发送数据
    117. strcat(buf,"*-*");
    118. if(send(newsdp,buf,sizeof(buf),0)<0)
    119. {
    120. ERR_MSG("send");
    121. return -1;
    122. }
    123. printf("发送成功\n");
    124. }
    125. return 0;
    126. }

    线程实现并发服务器 

    1. #include <stdio.h>
    2. #include <sys/types.h>
    3. #include <sys/socket.h>
    4. #include <arpa/inet.h>
    5. #include <netinet/in.h>
    6. #include <unistd.h>
    7. #include <string.h>
    8. #include <wait.h>
    9. #include <signal.h>
    10. #include <stdlib.h>
    11. #include <pthread.h>
    12. #define ERR_MSG(Msg) do{\
    13. fprintf(stderr,"__%d__:",__LINE__);\
    14. perror(Msg);\
    15. }while(0)
    16. #define IP "192.168.8.10"
    17. #define PORT 6666
    18. void *callback(void *arg);
    19. struct msg
    20. {
    21. struct sockaddr_in bin;
    22. int newsdp;
    23. };
    24. int main(int argc, const char *argv[])
    25. {
    26. //创建字节流式套接字
    27. int sdp=socket(AF_INET,SOCK_STREAM,0);
    28. if(sdp<0)
    29. {
    30. ERR_MSG("sdp");
    31. return -1;
    32. }
    33. //允许端口被重复使用
    34. int reuse = 1;
    35. if(setsockopt(sdp, SOL_SOCKET, SO_REUSEADDR, &reuse ,sizeof(reuse)) < 0)
    36. {
    37. ERR_MSG("setsockopt");
    38. return -1;
    39. }
    40. printf("允许端口快速重用\n");
    41. //将IP号和端口号绑定在套接字文件描述符
    42. struct sockaddr_in sin;
    43. sin.sin_family=AF_INET;
    44. sin.sin_port=htons(PORT);
    45. sin.sin_addr.s_addr=inet_addr(IP);
    46. socklen_t addrlen=sizeof(sin);
    47. if(bind(sdp,(struct sockaddr *)&sin,addrlen)<0)
    48. {
    49. ERR_MSG("bind");
    50. return -1;
    51. }
    52. printf("绑定成功\n");
    53. //将套接字设置为监听状态
    54. if(listen(sdp,128)<0)
    55. {
    56. ERR_MSG("listen");
    57. }
    58. printf("监听成功\n");
    59. struct sockaddr_in bin;
    60. socklen_t addrlen1=sizeof(bin);
    61. int newsdp=0;
    62. pthread_t tid;
    63. //生成新的文件描述符,存储链接成功的客户信息
    64. while(1)
    65. {
    66. newsdp=accept(sdp,(struct sockaddr *)&bin,&addrlen1);
    67. if(newsdp<0)
    68. {
    69. ERR_MSG("accept");
    70. return -1;
    71. }
    72. printf("对方客户端ip=[%s] port=%d连接成功 ",inet_ntoa(bin.sin_addr),ntohs(bin.sin_port));
    73. struct msg sendmsg;
    74. sendmsg.newsdp=newsdp;
    75. sendmsg.bin=bin;
    76. if(pthread_create(&tid,NULL,callback,(void *)&sendmsg)<0)
    77. {
    78. ERR_MSG("pthread_create");
    79. }
    80. }
    81. pthread_detach(tid);
    82. close(sdp);
    83. return 0;
    84. }
    85. void *callback(void *arg)
    86. {
    87. //接受数据
    88. char buf[128];
    89. int newsdp=((struct msg *)arg)->newsdp;
    90. struct sockaddr_in bin=((struct msg *)arg)->bin;
    91. bzero(buf,sizeof(buf));
    92. while(1)
    93. {
    94. ssize_t rcv;
    95. rcv=recv(newsdp,buf,sizeof(buf),0);
    96. if(rcv<0)
    97. {
    98. ERR_MSG("recv");
    99. break;
    100. }
    101. if(rcv==0)
    102. {
    103. printf("对方客户端关闭\n");
    104. break;
    105. }
    106. printf("对方客户端ip=[%s] port=%d newsdp=%d读取到的数据为%s\n",inet_ntoa(bin.sin_addr),ntohs(bin.sin_port),newsdp,buf);
    107. //发送数据
    108. strcat(buf,"*-*");
    109. if(send(newsdp,buf,sizeof(buf),0)<0)
    110. {
    111. ERR_MSG("send");
    112. break;
    113. }
    114. printf("发送成功\n");
    115. }
    116. close(newsdp);
    117. return 0;
    118. }

  • 相关阅读:
    你真的了解微服务架构吗?
    Leaflet 加载高德地图
    React组件间性能优化
    CORS就是跨域吗?
    UNPV2 学习:Posix Message Queues Exercise 解答记录
    【Linux】互斥量原理的实现
    手撕双链表
    Python连接MySQL、PostgreSQL数据库
    【李沐深度学习笔记】矩阵计算(2)
    说一下HashMap的实现原理?
  • 原文地址:https://blog.csdn.net/jinpaigangsi/article/details/128027485