1 /*
2 功能:实现并发服务器
3 简介:基于多线程实现
4 */
5 #include<stdio.h>
6 #include<stdlib.h>
7 #include<string.h>
8 #include<unistd.h>
9 #include<signal.h>
10 #include<sys/wait.h>
11 #include<arpa/inet.h>
12 #include<sys/socket.h>
13
14 #define BUF_SIZE 30 //无分号
15 void error_handling(char *message);
16 void read_childproc(int sig);
17
18 int main(int argc,char *argv[])
19 {
20 int serv_sock,clnt_sock;
21 struct sockaddr_in serv_adr,clnt_adr; //套接字结构体
22
23 pid_t pid;
24 struct sigaction act; //sinaction防止僵尸进程
25 socklen_t adr_sz;
26 int str_len,state;
27 char buf[BUF_SIZE];
28 if(argc!=2)
29 {
30 printf("Usage:%s <port>\n",argv[0]);
31 exit(1);
32 }
33 //sinaction结构体赋值 处理僵尸进程
34 act.sa_handler=read_childproc;
35 sigemptyset(&act.sa_mask);
36 act.sa_flags=0;
37 state=sigaction(SIGCHLD,&act,0);
38 //创建套接字
39 serv_sock=socket(PF_INET,SOCK_STREAM,0);
40 memset(&serv_adr,0,sizeof(serv_adr));
41 serv_adr.sin_family=AF_INET;
42 serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);
43 serv_adr.sin_port=htons(atoi(argv[1]));
44 //绑定ip和端口号
45 if(bind(serv_sock,(struct sockaddr*)&serv_adr,sizeof(serv_adr))==-1)
46 error_handling("bind error");
47 //监听
48 if(listen(serv_sock,5)==-1)
49 error_handling("listen error");
50
51 while(1)
52 {
53 adr_sz=sizeof(clnt_adr);
54 //客户端套接字accept
55 clnt_sock=accept(serv_sock,(struct sockaddr*)&clnt_adr,&adr_sz);
56 if(clnt_sock==-1)
57 continue;
58 else
59 puts("new client connected...");
60 //fork创建多进程
61 pid = fork();
62 if(pid==-1)
63 {
64 close(clnt_sock);
65 continue;
66 }
67 //子进程运行
68 if(pid==0)
69 {
70 close(serv_sock);
71 while((str_len=read(clnt_sock,buf,BUF_SIZE))!=0)
72 write(clnt_sock,buf,str_len);
73
74 close(clnt_sock);
75 puts("client disconnected....");
76 return 0;
77 }
78 else
79 close(clnt_sock);
80 }
81 close(serv_sock);
82 return 0;
83 }
84
85 void read_childproc(int sig)
86 {
87 pid_t pid;
88 int status;
89 //狙杀僵尸进程
90 pid=waitpid(-1,&status,WNOHANG);
91 printf("removid proc id:%d \n",pid);
92 }
93 void error_handling(char *message)
94 {
95 fputs(message,stderr);
96 fputc(‘\n‘,stderr);
97 exit(1);
98 }
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include<unistd.h>
5 #include<arpa/inet.h>
6 #include<sys/socket.h>
7
8 #define BUF_SIZE 1024
9 void error_handling(char *message);
10
11 int main(int argc, char *argv[])
12 {
13 int sock;
14 char message[BUF_SIZE];
15 int str_len;
16
17 struct sockaddr_in serv_adr;
18 socklen_t clnt_adr_sz;
19
20 if(argc != 3)
21 {
22 printf("Usage:%s <port>\n",argv[0]);
23 exit(1);
24 }
25
26 //创建客户端套接字
27 sock = socket(PF_INET, SOCK_STREAM,0);
28 if(sock == -1)
29 {
30 error_handling("socket() error");
31 }
32
33 //初始化地址信息 值为目标服务器套接字的IP和端口号
34 memset(&serv_adr, 0, sizeof(serv_adr));
35 serv_adr.sin_family = AF_INET;
36 serv_adr.sin_addr.s_addr = inet_addr(argv[1]);
37 serv_adr.sin_port = htons(atoi(argv[2]));
38
39 //客户端请求连接 成功0 失败-1 --客户端IP地址和端口在调用connect函数时自动分配,无需标记bind()进行分配
40 if(connect(sock,(struct sockaddr*)&serv_adr, sizeof(serv_adr))==-1) //connect(客户端套接字描述符,调用完后保存目标服务器地址信息,第二参数的长度)
41 error_handling("connect() error");
42 else
43 puts("connected.....");
44
45 while(1)
46 {
47 fputs("Input message(Q to quit):",stdout);
48 fgets(message,BUF_SIZE,stdin);
49
50 if(!strcmp(message,"q\n") || !strcmp(message,"Q\n"))
51 break;
52 write(sock,message,strlen(message));
53 str_len = read(sock,message,BUF_SIZE-1); //read()接受服务器端数据
54 message[str_len]=0;
55 printf("message from server:%s",message);
56 }
57 close(sock);
58 return 0;
59 }
60
61 void error_handling(char *message)
62 {
63 fputs(message,stderr);
64 fputc(‘\n‘,stderr);
65 exit(1);
66 }
1 zyp@zyp-ubuntu:~/project$ gcc echo_mpserv.c -o mpserv
2 zyp@zyp-ubuntu:~/project$ ./mpserv 9190
3 new client connected...
4 new client connected...
5 client disconnected....
6 removid proc id:25062
7 client disconnected....
8 removid proc id:25032
1 zyp@zyp-ubuntu:~/project$ ./elient 127.0.0.1 9190
2 connected.....
3 Input message(Q to quit):this is client 2 hello server
4 message from server:this is client 2 hello server
5 Input message(Q to quit):q
6 zyp@zyp-ubuntu:~/project$
1 Input message(Q to quit):this is client1 hello server
2 message from server:this is client1 hello server
3 Input message(Q to quit):q