思维导图
多进程并发服务器
#include<myhead.h>
#define SER_IP "192.168.122.56"
#define SER_PORT 8888
void handler(int signo)
{if(signo==SIGCHLD){while(waitpid(-1,NULL,WNOHANG)>0);}
}
int main(int argc, char *argv[])
{//将SIGCHLD信号与处理函数绑定if(signal(SIGCHLD,handler)==SIG_ERR){perror("signal");return -1;}//创建套接字int sfd=socket(AF_INET,SOCK_STREAM,0);if(sfd==-1){perror("socket");return -1;}printf("socket success sfd=%d\n",sfd);//端口快速重用int reuse=1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){perror("setsockopt");return -1;}printf("端口号快速重用成功\n");//绑定ip地址和端口//填充地址信息结构体struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SER_PORT);sin.sin_addr.s_addr=inet_addr(SER_IP);//绑定if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("bind");return -1;} printf("bind success\n");//将套接字设置成被动监听状态if(listen(sfd,128)==-1){perror("listen");return -1;}printf("listen success\n");//阻塞等待客户端连接//第二个参数->我要记录发送连接方的地址信息结构体struct sockaddr_in cin;socklen_t socklen=sizeof(cin);while(1){int newfd=accept(sfd,(struct sockaddr*)&cin,&socklen);if(newfd==-1){perror("accept");return -1;}printf("[%s:%d]:已连接,newfd=%d\n",\inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd);pid_t pid=fork();if(pid>0){//accept创了一个newfd,父进程中不使用,关闭close(newfd);}else if(pid==0){//数据通信char rbuf[128]="";while(1){bzero(rbuf,sizeof(rbuf));int ret = recv(newfd,rbuf,sizeof(rbuf),0);if(ret==0){printf("客户端已下线\n");break;}printf("[%s:%d]:%s\n",\inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),rbuf);strcat(rbuf,"*_*");send(newfd,rbuf,strlen(rbuf),0);printf("发送成功\n");}close(newfd);exit(EXIT_SUCCESS);}}close(sfd);return 0;
}
多线程并发服务器
#include<myhead.h>
#define SER_IP "192.168.122.56"
#define SER_PORT 8888
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 rbuf[128]="";while(1){bzero(rbuf,sizeof(rbuf));int ret = recv(newfd,rbuf,sizeof(rbuf),0);if(ret==0){printf("客户端已下线\n");break;}printf("[%s:%d]:%s\n",\inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),rbuf);strcat(rbuf,"*_*");send(newfd,rbuf,strlen(rbuf),0);printf("发送成功\n");}close(newfd);pthread_exit(NULL);
}
int main(int argc, char *argv[])
{//创建套接字int sfd=socket(AF_INET,SOCK_STREAM,0);if(sfd==-1){perror("socket");return -1;}printf("socket success sfd=%d\n",sfd);//端口快速重用int reuse=1;if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse))==-1){perror("setsockopt");return -1;}printf("端口号快速重用成功\n");//绑定ip地址和端口//填充地址信息结构体struct sockaddr_in sin;sin.sin_family=AF_INET;sin.sin_port=htons(SER_PORT);sin.sin_addr.s_addr=inet_addr(SER_IP);//绑定if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))==-1){perror("bind");return -1;} printf("bind success\n");//将套接字设置成被动监听状态if(listen(sfd,128)==-1){perror("listen");return -1;}printf("listen success\n");//阻塞等待客户端连接//第二个参数->我要记录发送连接方的地址信息结构体struct sockaddr_in cin;socklen_t socklen=sizeof(cin);while(1){int newfd=accept(sfd,(struct sockaddr*)&cin,&socklen);if(newfd==-1){perror("accept");return -1;}printf("[%s:%d]:已连接,newfd=%d\n",\inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd);//定义用于传参的变量struct MsgInfo info={newfd,cin};//创建分支线程用于通信pthread_t tid=-1;if(pthread_create(&tid,NULL,deal_cli_msg,&info)==-1){printf("创建线程失败\n");return -1;}//回收分支线程的资源pthread_detach(tid);}close(sfd);return 0;
}
流式域套接字服务器
#include<myhead.h>
int main(int argc, char *argv[])
{//创建套接字int sfd=socket(AF_UNIX,SOCK_STREAM,0);if(sfd==-1){perror("socket");return -1;}printf("socket success sfd=%d\n",sfd);//判断要绑定的套接字文件是否存在if(access("./unix",F_OK)==0){//说明文件存在,将其删除if(unlink("./unix")!=0){perror("unlink");return -1;}}//绑定ip地址和端口//填充地址信息结构体struct sockaddr_un sun;sun.sun_family=AF_UNIX;strcpy(sun.sun_path,"./unix");//绑定if(bind(sfd,(struct sockaddr*)&sun,sizeof(sun))==-1){perror("bind");return -1;} printf("bind success\n");//将套接字设置成被动监听状态if(listen(sfd,128)==-1){perror("listen");return -1;}printf("listen success\n");//阻塞等待客户端连接//第二个参数->我要记录发送连接方的地址信息结构体struct sockaddr_un cun;socklen_t socklen=sizeof(cun);int newfd=accept(sfd,(struct sockaddr*)&cun,&socklen);if(newfd==-1){perror("accept");return -1;}printf("[%s]:已连接,newfd=%d\n",cun.sun_path,newfd);//数据通信char rbuf[128]="";while(1){bzero(rbuf,sizeof(rbuf));int ret = recv(newfd,rbuf,sizeof(rbuf),0);if(ret==0){printf("客户端已下线\n");break;}printf("[%s]:%s\n",cun.sun_path,rbuf);strcat(rbuf,"*_*");send(newfd,rbuf,strlen(rbuf),0);printf("发送成功\n");}close(sfd);close(newfd);return 0;
}
流式域套接字客户端
#include<myhead.h>
int main(int argc, char *argv[])
{int cfd=socket(AF_UNIX,SOCK_STREAM,0);if(cfd==-1){perror("socket");return -1;}printf("socket success\n");if(access("./linux",F_OK)==0){if(unlink("./linux")!=0){perror("unlink");return -1;}}//绑定ip地址和端口 //填充地址信息结构体struct sockaddr_un cun;cun.sun_family=AF_UNIX;strcpy(cun.sun_path,"./linux");//绑定if(bind(cfd,(struct sockaddr*)&cun,sizeof(cun))==-1){perror("bind");return -1;}struct sockaddr_un sun;sun.sun_family=AF_UNIX;strcpy(sun.sun_path,"./unix");if(connect(cfd,(struct sockaddr*)&sun,sizeof(sun))==-1){perror("connect");return -1;}printf("connect success\n");char wbuf[128]="";while(1){printf("请输入>>>>");fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]='\0';if(strcmp(wbuf,"quit")==0){break;}send(cfd,wbuf,strlen(wbuf),0);bzero(wbuf,sizeof(wbuf));recv(cfd,wbuf,sizeof(wbuf),0);printf("收到消息为:%s\n",wbuf);}close(cfd);return 0;
}
报式域套接字服务器
#include<myhead.h>
int main(int argc, char *argv[])
{//创建套接字int sfd=socket(AF_UNIX,SOCK_DGRAM,0);if(sfd==-1){perror("socket");return -1;}printf("socket success sfd=%d\n",sfd);//判断要绑定的套接字文件是否存在if(access("./unix",F_OK)==0){//说明文件存在,将其删除if(unlink("./unix")!=0){perror("unlink");return -1;}}//绑定ip地址和端口//填充地址信息结构体struct sockaddr_un sun;sun.sun_family=AF_UNIX;strcpy(sun.sun_path,"./unix");//绑定if(bind(sfd,(struct sockaddr*)&sun,sizeof(sun))==-1){perror("bind");return -1;} printf("bind success\n");//第二个参数->我要记录发送连接方的地址信息结构体struct sockaddr_un cun;socklen_t socklen=sizeof(cun);//数据通信char rbuf[128]="";while(1){bzero(rbuf,sizeof(rbuf));recvfrom(sfd,rbuf,sizeof(rbuf),0,(struct sockaddr*)&cun,&socklen);printf("[%s]:%s\n",cun.sun_path,rbuf);strcat(rbuf,"*_*");if(sendto(sfd,rbuf,sizeof(rbuf),0,(struct sockaddr*)&cun,sizeof(cun))==-1){perror("sendto");return -1;}printf("发送成功\n");}close(sfd);return 0;
}
报式域套接字客户端
#include<myhead.h>
int main(int argc, char *argv[])
{int cfd=socket(AF_UNIX,SOCK_DGRAM,0);if(cfd==-1){perror("socket");return -1;}printf("socket success\n");//判断要绑定的套接字文件是否存在if(access("./linux",F_OK)==0){//说明文件存在,将其删除if(unlink("./linux")!=0){perror("unlink");return -1;}}struct sockaddr_un cun;cun.sun_family=AF_UNIX;strcpy(cun.sun_path,"./linux");if(bind(cfd,(struct sockaddr*)&cun,sizeof(cun))==-1){perror("bind");return -1;}struct sockaddr_un sun;sun.sun_family=AF_UNIX;strcpy(sun.sun_path,"./unix");char wbuf[128]="";while(1){printf("请输入>>>>");fgets(wbuf,sizeof(wbuf),stdin);wbuf[strlen(wbuf)-1]=0;sendto(cfd,wbuf,strlen(wbuf),0,(struct sockaddr*)&sun,sizeof(sun));printf("发送成功\n");recvfrom(cfd,wbuf,sizeof(wbuf),0,NULL,NULL);printf("收到服务器消息:%s\n",wbuf);}close(cfd);return 0;
}