linux下的C socket编程(4)

 

延长server的生命周期:

    在前面的一个个例子中,server在处理完一个链接之后便会立即结束掉自己,然而这种server并不科学,server因该使能够一直接受处理连接的,知道结束命令结束掉server。

实现这种情况的最简单的方法就是将accept()放置在一个死循环中,使得它能够一直的接受新的                   连接。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include<stdio.h>
#include<strinh.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/types.h>
#include<unistd.h>
#include<netinet/in.h>
 
int main()
{
int socket_desc,new_socket;
struct sockadddr_in server,client;
char * message;
 
sock_desc= socket(AF_INET,SOCKE_TREAM,0);
 
if(-1== sock_desc)
{
perror("socket");
exit(1);
}
 
server.sin_family= AF_INET;
server.sin_port = htons(8888);
server.sin_addr_s_addr = INADDR_ANY;
 
if(bind(sock_desc,(struct sockaddr*)&server,sizeof(server))<0)
{
perror("bind");
exit(1);
}
puts("bind success");
 
listen(sock_desc,5);
puts("waiting for incoing connectiongs");
 
socklen_t socklen_size = sizeof(sockaddr_in);
while(new_socket=accept(sock_desc,(struct sockaddr*)&client,&socklen_size))
{
puts("waiting for incoing connectiongs...");
message= "hello world \n";
send(new_socket,message,strlen(message),0);
}
if(new_socket<0)
{
perror("accept error");
exit(1);
}
close(new_socket);
close(sock_desc);
return 0;

再次运行代码,向server发起多个请求,server都能够收到,不信可以试试。

    到现在为止,server端的全部功能都已经实现,然而实现的这个server比较鸡肋,他每次只能处理一个请求,当多个请求来临时就会阻塞掉后面的请求,直到当前的请求处理完成。

所以我们现在应该想办法让它能够同时处理多个连接。

多线程处理多个连接:

为了处理每一个连接请求,我们都需要为他们单独的运行一份代码,我们需要使得一份代码能过单独的运行,实现这种功能的方法有很多,这里就暂且说说多线程的方法:

    当主程序接收到新的连接后,会创建一个新的线程去处理这个链接的事务,之后主程序会回去继续接受新的连接。

在linux中我们使用pthread(posix threads)库来使用多线程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#inlcude<sys/types.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<netinet/in.h>
 
#define port 8888
 
void * connection_handler(void*);
 
int main()
{
int sock_desc,new_socket,* thread_socket;
struct sockaddr_in server,client;
scoklen_t client_len ;
char * message;
sock_desc= socket(AF_INET,SOCK_STREAM,0);
if(-1==sock_desc)
{
perror("socket");
exit(EXIT_FAILURE);
}
server.sin_family = AF_INET;
server.sin_port = htons(port);
server.sin_addr.s_addr = INADDR_ANY;
 
if(bind(sock_desc,(struct sockaddr*)&server,sizeof(server))<0
{
perror("bind");
exit(EXIT_FAILURE);
}
puts("bind ok");
 
listen(sock_desc,5);
 
puts("waiting for incoming connections...");
 
client_len = sizeof(client);
while((new_socket= accept(sock_desc,(struct sockaddr*)&client,&client_len)))
{
puts("connections accepted");
message = "hello client ,now i will assign a handler for you \r\n";
send(now_socket,message,sizeof(message),0);
pthread_t sniffer_thread;
*thread_socket = new_socket;
if(pthread_create(&sniffer_thread,NULL,connection_handler,(void *)thread_socket)<0)
{
perror("cannot create thread");
exit(EXIT_FAILURE);
}
puts(Handler assigned);
}
if(new_socket<0)
{
perror("accept failed ");
exit(FAILURE);
}
return 0;
}
void * connection_handler(void * sock_desc)
{
int socket = * (int *)sock_desc;
char *message;
message = "into connection handler\n";
send(socket,message,sizeof(message),0);
message= "communicate with client \n";
send(socket,message,sizeof(message),0);
return 0;
}

OK,到现在基本的socket编程的知识点基本全部说清楚了,后面需要在实践项目中不断使用,巩固能力。