所谓多线程并发服务器就是基于线程,每个客户端来了创建一个线程,由线程去处理客户端的请求。相对于多线程服务器来说,多进程服务器在创建进程时要消耗较大的系统资源,所以我们使用线程来取代进程,这样服务处理程序可以较快的创建。
据统计,创建线程与创建进程要快 10100 倍,所以又把线程称为“轻量级”进程。线程与进程不同的是:一个进程内的所有线程共享相同的全局内存、全局变量等信息,这种机制又带来了同步问题。
CP多线程并发服务器处理框架:
#include"头文件"
int main()
{
创建套接字sockfd
绑定套接字(bind)
监听套接字(listen)
while(1)
{
int connfd = accept(....);
pthread_t thread_tid;
pthread_create(...);
pthread_detch(thread_tid);
}
close(sockfd);
return 0;
}
//线程处理函数
void* fun(coid* arg)
{
int connfd = (int)arg;
fun();//处理函数
close(connfd);
}
接下来是一个例子:
utili.h
#include
#include
#include
#include
#include
#include
#include
#define PORT 8888
ser.c
#include"utili.h"
void* client_fun(void *arg)
{
int recvlen = 0;
char recvbuf[1024] = "";
int connfd = (int)arg;
while((recvlen = recv(connfd,recvbuf,sizeof(recvbuf),0))>0)
{
printf("recv_buf: %s\n", recvbuf);
send(connfd, recvbuf, recvlen, 0);
}
printf("client closed!\n");
close(connfd);
return NULL;
}
int main()
{
int sockfd;
int log;
int connfd;
pthread_t thread_id;
//chushihua
struct sockaddr_in server,client;
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = htonl(INADDR_ANY);
//创建套接字
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0)
printf("socket create error\n");
log = bind(sockfd,(struct sockaddr*)&server,sizeof(server));
if(log < 0)
{
printf("bindfd error\n");
close(sockfd);
exit(-1);
}
log = listen(sockfd,20);
if(log < 0)
{
printf("listen error\n");
close(sockfd);
exit(-1);
}
printf("waiting client >>>>>\n");
while(1)
{
socklen_t client_len = sizeof(client);
//accept
connfd = accept(sockfd,(struct sockaddr*)&client,&client_len);
if(connfd < 0)
{
printf("connfd error\n");
continue;
}
char cli_ip[INET_ADDRSTRLEN] = "";
inet_ntop(AF_INET, &client.sin_addr, cli_ip, INET_ADDRSTRLEN);
printf("----------------------------------------------\n");
printf("client ip=%s,port=%d\n", cli_ip,ntohs(client.sin_port));
pthread_create(&thread_id,NULL,(void*)client_fun,(void*)connfd);
pthread_detach(thread_id);//线程分离,结束时自动回收线程
}
close(sockfd);
return 0;
}
cli.c
#include"utili.h"
int main()
{
int sockfd;
int log;
struct sockaddr_in server;
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = htonl(INADDR_ANY);
sockfd = socket(AF_INET,SOCK_STREAM,0);
if(sockfd < 0)
{
printf("sockfd error\n");
exit(-1);
}
log = connect(sockfd,(struct sockaddr*)&server,sizeof(server));
if(log < 0)
{
printf("connect error\n");
close(sockfd);
exit(-1);
}
char sendbuf[1024];
char recvbuf[1024];
while(1)
{
fgets(sendbuf,sizeof(sendbuf),stdin);
send(sockfd,sendbuf,strlen(sendbuf),0);
recv(sockfd,recvbuf,sizeof(recvbuf),0);
fputs(recvbuf,stdout);
memset(sendbuf, 0, sizeof(sendbuf));
memset(recvbuf, 0, sizeof(recvbuf));
}
close(sockfd);
return 0;
}