多进程程实现TCP并发服务器
c
复制代码
#include<myhead.h>
#define IP "192.168.27.227"
#define PORT 8888
#define handel_err(res,val) if(val==-1){perror(res);return-1;}
void handel(int n){
if(n==SIGCHLD){
while(waitpid(-1,NULL,WNOHANG)>0);
}
}
int main(int argc, const char *argv[])
{
//收尸
if(signal(SIGCHLD,handel)==SIG_ERR){
perror("signal");
}
//套接字
int sfd=socket(AF_INET,SOCK_STREAM,0);
handel_err("socket",sfd);
//绑定
struct sockaddr_in server={
.sin_family=AF_INET,
.sin_port=htons(PORT),
.sin_addr.s_addr=inet_addr(IP)
};
int res=bind(sfd,(struct sockaddr *)&server,sizeof(server));
handel_err("bind",res);
//监听
res = listen(sfd,10);
handel_err("listen",res);
struct sockaddr_in client;
socklen_t addrlen=sizeof(client);
while(1){
int cfd=accept(sfd,(struct sockaddr *)&client,&addrlen);
handel_err("accept",res);
char buf[1024];
//创建线程
int pid = fork();
if(pid>0){
//关闭cfd
close(cfd);
}else if(pid == 0){
//关闭sfd
close(sfd);
char buf[1024]="";
while(1){
bzero(buf,sizeof(buf));
int res=recv(cfd,buf,sizeof(buf),0);
if(res==0||res==-1){
printf("下线\n");
close(cfd);
break;
}
printf("-->%s\n",buf);
send(cfd,"ok\n",sizeof("ok\n"),0);
}
//退出子
exit(EXIT_SUCCESS);
}
}
close(sfd);
return 0;
}
循环服务器
c
复制代码
#include<myhead.h>
#define handel_err(res,val) if(val==-1){perror(res);return-1;}
int res;
#define PORT 8888
#define IP "192.168.27.227"
int main(int argc, const char *argv[])
{
int sfd=socket(AF_INET,SOCK_STREAM,0);
handel_err("socket",sfd);
//快速复用
/*int k=1;
res=setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&k,sizeof(k));
*/
//绑定
struct sockaddr_in server={
.sin_family=AF_INET,
.sin_port=htons(PORT),
.sin_addr.s_addr=inet_addr(IP)
};
res=bind(sfd,(struct sockaddr *)&server,sizeof(server));
handel_err("bing",res);
//监听
res=listen(sfd,10);
handel_err("listen",res);
int cfd;
struct sockaddr_in client;
socklen_t client_len;
while(1){
cfd=accept(sfd,(struct sockaddr*)&client,&client_len);
handel_err("accept",cfd);
char buf[1024];
while(1){
bzero(buf,sizeof(buf));
res=recv(cfd,buf,sizeof(buf),0);
if(res==0){
printf("x\n");
close(cfd);
break;
}
printf("-->%s\n",buf);
send(cfd,"ok\n",sizeof("ok\n"),0);
}
}
close(sfd);
return 0;
}
多线程服务器
c
复制代码
#include<myhead.h>
#define SER_PORT 6666 //服务器端口号
#define SER_IP "192.168.0.136" //服务器ip地址
struct MsgInfo
{
int newfd; //套接字文件描述符
struct sockaddr_in cin; //客户端地址信息结构体
};
void *deal_cli_msg(void *arg)
{
int newfd = (*(struct MsgInfo*)arg).newfd;
struct sockaddr_in cin = (*(struct MsgInfo*)arg).cin;
char buf[128] = "";
while(1)
{
//清空容器
bzero(buf, sizeof(buf));
//从客户端套接字中读取数据
int res = recv(newfd, buf, sizeof(buf), 0);
if(res == -1)
{
perror("read error");
return NULL;
}else if(res == 0)
{
printf("客户端已经下线\n");
close(newfd); //关闭客户端套接字
break;
}
//正常收到客户端发来的消息
printf("[%s:%d] : %s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);
//将消息回复给客户端
if(send(newfd, buf, strlen(buf), 0) == -1)
{
perror("发送error");
return NULL;
}
printf("发送成功\n");
}
//退出线程
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
int sfd = socket(AF_INET, SOCK_STREAM, 0);
if(sfd == -1)
{
perror("socket error");
return -1;
}
int reuse = 1;
if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))==-1)
{
perror("setsockopt error");
return -1;
}
struct sockaddr_in sin;
sin.sin_family = AF_INET; //通信域
sin.sin_port = htons(SER_PORT); //端口号
sin.sin_addr.s_addr = inet_addr(SER_IP); //ip地址
if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin)) == -1)
{
perror("bind error");
return -1;
}
printf("bind success\n");
if(listen(sfd, 128)==-1)
{
perror("listen error");
return -1;
}
printf("listen success\n");
struct sockaddr_in cin; //用于接收地址信息
socklen_t addrlen = sizeof(cin); //用于接收长度
while(1)
{
int newfd = accept(sfd, (struct sockaddr*)&cin, &addrlen) ;
if(newfd == -1)
{
perror("accept error");
return -1;
}
printf("[%s:%d:%d]: 已成功连接一个客户端\n", \
inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), newfd);
struct MsgInfo buf = {newfd, cin};
pthread_t tid = -1;
if(pthread_create(&tid, NULL, deal_cli_msg, &buf) != 0)
{
printf("pthread_create error\n");
return -1;
}
pthread_detach(tid); //将线程设置成分离态
}
close(sfd);
return 0;
}