socket编程之并发回射服务器3
Posted Sawyer Ford
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了socket编程之并发回射服务器3相关的知识,希望对你有一定的参考价值。
在socket编程之并发回射服务器一文中,服务器采用多进程的方式实现并发,本文采用多线程的方式实现并发。
多线程相关API:
// Compile and link with -pthread int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
int pthread_join(pthread_t thread, void **retval); int pthread_detach(pthread_t thread);
pthread_join类似waitpid,用于等待一个线程的结束。
pthread_detach将线程状态变成detachable。
一个detachable线程终止后,它的资源自动释放回系统,不需要其他线程join。
具体代码如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <signal.h> #include <sys/wait.h> #include <sys/errno.h> #include <pthread.h> #define MAXLINE 4096 #define LISTENQ 10 #define PORT 8888 void doEcho(int sockfd) { char buff[MAXLINE]; while (true) { memset(buff, 0, sizeof(buff)); int n = read(sockfd, buff, MAXLINE); if (n < 0) { perror("read error"); exit(1); } else if (n == 0) { printf("client closed\\n"); break; } fputs(buff, stdout); write(sockfd, buff, n); } } static void* doit(void *arg) { int sockfd = *(int*)arg; free(arg); pthread_detach(pthread_self()); doEcho(sockfd); close(sockfd); return (NULL); } int main(int argc, char **argv) { int listenfd, connfd; pthread_t tid; socklen_t clilen; struct sockaddr_in servaddr, cliaddr; if ( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket error"); exit(1); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(PORT); if ( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) { perror("bind error"); exit(1); } if ( listen(listenfd, LISTENQ) < 0) { perror("listen error"); exit(1); } for ( ; ; ) { clilen = sizeof(cliaddr); if ( (connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &clilen)) < 0) { if (errno == EINTR) { continue; } else { perror("accept error"); exit(1); } } int *pconnfd = (int*)malloc(sizeof(int)); *pconnfd = connfd; pthread_create(&tid, NULL, &doit, pconnfd); } }
需要注意的是给新线程传递参数的方法,不能直接传递connfd。
以上是关于socket编程之并发回射服务器3的主要内容,如果未能解决你的问题,请参考以下文章
(P9)socket编程四:流协议与粘(nian)包,粘包产生的原因,粘包处理方案,readn,writen 6.回射客户/服务器