程序简介:这是一个基本的多线程服务器模型。当一个客户端连接上服务器时,服务器就产生一个子线程来与客户端进行通信。这种通信机制效率比较低,但高于一个连接产生一个子进程的多进程服务器模型,和多进程服务器模型一样,最大连接数会受到系统的最大子线程数的限制。
上代码:
#include "my_unp.h"
void str_echo(int sockfd)
{
ssize_t n;
char buf[MAXLINE];
again:
//从套接字中读取数据,写到buffer中去
//再将buffer中的数据写到套接字中去
while( (n=read(sockfd, buf, MAXLINE)) > 0 )
Writen(sockfd, buf, n);
//由于信号中断,没写或读成功任何数据
if( n<0 && errno==EINTR )
goto again;
else if( n < 0 )
error_quit("str_echo: read error");
}
static void *doit(void *arg)
{
int connfd;
connfd = *((int *) arg);
free(arg);
//子线程不阻塞父线程
Pthread_detach(pthread_self());
//处理数据
str_echo(connfd);
//关闭连接
Close(connfd);
return(NULL);
}
int main(int argc, char **argv)
{
int listenfd, *iptr;
pthread_t tid;
socklen_t addrlen, len;
struct sockaddr *cliaddr;
struct sockaddr_in servaddr;
//开始监听
listenfd = Socket(AF_INET, SOCK_STREAM, 0);
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
addrlen = sizeof(struct sockaddr);
//把socket和socket地址结构联系起来
Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));
//开始监听LISTENQ端口
Listen(listenfd, LISTENQ);
cliaddr = Malloc(addrlen);
while(1)
{
len = addrlen;
iptr = Malloc(sizeof(int));
*iptr = Accept(listenfd, cliaddr, &len);
//为每个连接新建一个线程
Pthread_create(&tid, NULL, &doit, iptr);
}
return 0;
}