并发编程典型框架
服务器阻塞于accept函数调用,当客户端申请连接请求时客户端与服务器的状态
从accept函数返回后,新的连接被内核接受,创建新的connfd套接字
通过fork父进程可以创建子进程,让其代替自己完成读写数据操作
此时listenfd与connfd被父子进程所共享,接下来父进程关闭连接套接字只负责监听,但父进程可再次调用accept函数准备处理下一个客户端连接请求,而子进程关闭监听套接字只负责读写数据
服务器代码
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
int main(int argc,char * argv[])
{
pid_t pid;
int listenfd,connfd=0;
char sendbuf[100]= {"success"},revbuf[100]= {};
struct sockaddr_in ser,clt;
socklen_t len=sizeof(clt);
listenfd=socket(AF_INET,SOCK_STREAM,0);
ser.sin_family = AF_INET;
ser.sin_port = htons(8001);
ser.sin_addr.s_addr = inet_addr("127.0.0.1");
int optval=1;
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))< 0)
{
printf("setsockopt bind error!\n");
exit(0);
}
if(bind(listenfd,(struct sockaddr*)&ser,sizeof(ser))<0)
{
printf("bind failed!\n");
exit(0);
}
if(listen(listenfd,SOMAXCONN)<0)
{
printf("listen failed!\n");
exit(0);
}
while(1)
{
connfd=accept(listenfd,(struct sockaddr*)&clt,(socklen_t *)&len);
if(connfd==-1)
{
printf("connect failed!\n");
}
pid=fork();
if(pid==0)
{
close(listenfd);
printf("child process running\n");
while(1)
{
int ret=read(connfd,revbuf,sizeof(revbuf));
if(ret<0)
{
printf("read failed!\n");
exit(0);
}
else if(ret==0)
{
printf("client closed\n");
exit(0);
}
printf("server revmsg:%s\n",revbuf);
write(connfd,sendbuf,sizeof(sendbuf));
memset(revbuf,0,sizeof(revbuf));
}
}
else if(pid>0)
{
close(connfd);
}
else
{
printf("create failed!\n");
close(connfd);
close(listenfd);
exit(0);
}
}
if(pid==0)
{
close(connfd);
}
else
{
close(listenfd);
}
return 0;
}
客户端代码
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<string.h>
int main(int argc,char *argv[])
{
struct sockaddr_in user;
int sockfd;
char sendbuf[100],revbuf[100];
sockfd=socket(AF_INET,SOCK_STREAM,0);
if(sockfd==-1)
{
printf("socket failed!\n");
exit(0);
}
user.sin_family = AF_INET;
user.sin_port = htons(8001);
user.sin_addr.s_addr = inet_addr("127.0.0.1");
if ( connect(sockfd, (struct sockaddr*) (&user), sizeof(user)) < 0)
{
perror("connect failed!\n");
exit(0);
}
while(~scanf("%s",sendbuf))
{
write(sockfd,sendbuf,sizeof(sendbuf));
read(sockfd,revbuf,sizeof(revbuf));
printf("client revmsg:%s\n",revbuf);
memset(sendbuf,0,sizeof(sendbuf));
memset(sendbuf,0,sizeof(revbuf));
}
close(sockfd);
return 0;
}