Linux下socket程式設計之多執行緒TCP伺服器
阿新 • • 發佈:2019-01-22
程式碼如下:
thread_server.c
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<pthread.h>
#include<arpa/inet.h>
#include<unistd.h>
void usage(char* proc)
{
printf("%s [ip][port]\n" ,proc);
}
int startup(char* ip,int port)
{
int sock=socket(AF_INET,SOCK_STREAM,0);
if(sock<0)
{
perror("socket");
return 2;
}
struct sockaddr_in local;
local.sin_family=AF_INET;
local.sin_port=htons(port);
local.sin_addr.s_addr=inet_addr(ip);
int opt=1 ;
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
if((bind(sock,(struct sockaddr*)&local,sizeof(local)))<0)
{
perror("bing");
return 3;
}
if(listen(sock,10)<0)
{
perror("listen");
close(sock);
exit(4);
}
return sock;
}
void handler(char* arg)
{
int sock=(int)arg;
char buff[1024];
while(1)
{
ssize_t s = read(sock,buff,sizeof(buff));
if(s >0)
{
buff[s] = '\0';
printf("client:#%s",buff);
const char* msg = "HTTP/1.1 200 OK\r\n\r\n<html><h1>This is title</h1></html>\r\n";
write(sock,msg,strlen(msg));
}
if(s==0)
{
break;
}
}
printf("client quit!\n");
fflush(stdout);
}
int main(int argc,char* argv[])
{
if(argc<3)
{
usage(argv[0]);
return 1;
}
int listen_sock=startup(argv[1],atoi(argv[2]));
struct sockaddr_in client_addr;
socklen_t len=sizeof(client_addr);
while(1)
{
int new_sock=accept(listen_sock,(struct sockaddr *)&client_addr,&len);
if(new_sock<0)
{
perror("accept");
return 5;
}
char ipbuff[INET_ADDRSTRLEN];
memset(ipbuff,'\0',sizeof(ipbuff));
inet_ntop(AF_INET,&client_addr.sin_addr,ipbuff,sizeof(ipbuff));
printf("get connect,ip is %s,port is %d\n",ipbuff,ntohs(client_addr.sin_port));
pthread_t tid;
pthread_create(&tid, NULL, handler, (void*)new_sock); //建立執行緒執行handler
pthread_detach(tid);//將子執行緒與主執行緒分離
}
close(listen_sock);
return 0;
}
與tcp和tcp多程序伺服器端差別不大,原來是交給一個程序處理,現在是交給一個執行緒,都類似,不做多的解釋,客戶端還是看最開始版本tcp客戶端,不在這裡多寫,程式碼都一樣。
實驗效果圖:
伺服器端:
客戶端1:
客戶端2:
歡迎評論