近日研究socket 通信,学习了如下的一篇文章:
http://blog.csdn.net/dlutcat/article/details/1813933
感觉很好,但还有一点不过瘾,就想着能否加点料:增加多个客户端,让他们一起和服务器端通信。
为了区别各个客户端,把客户端里加入了识别自身hostname的一段。
#define HELLO_WORLD_SERVER_PORT 6666
#define LENGTH_OF_LISTEN_QUEUE 20
while( wait3(&status,WNOHANG,(struct rusage*)0) >=0 )
int main(int argc, char **argv)
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htons(INADDR_ANY);
server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
int server_socket = socket(AF_INET,SOCK_STREAM,0);
printf("Create Socket Failed!");
if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr))){
printf("Server Bind Port : %d Failed!", HELLO_WORLD_SERVER_PORT);
fprintf(stderr,"Before Main Process listen.\n");
if ( listen(server_socket, LENGTH_OF_LISTEN_QUEUE) ){
printf("Server Listen Failed!");
fprintf(stderr, "After Main Process listen.\n");
(void)signal(SIGCHLD,reaper);
struct sockaddr_in client_addr;
socklen_t length = sizeof(client_addr);
fprintf(stderr,"Before accept. In %d.\n",getpid());
accept(server_socket,(struct sockaddr*)&client_addr,&length);
if ( new_server_socket < 0){
printf("Server Accept Failed!\n");
fprintf(stderr,"After accept. In %d.\n",getpid());
int child_process_pid = fork();
if(child_process_pid == 0 ){
fprintf(stderr,"Child. %d born.\n",getpid());
char buffer[BUFFER_SIZE];
bzero(buffer, BUFFER_SIZE);
strcpy(buffer,"Hello,World! FromServer! ");
send(new_server_socket,buffer,BUFFER_SIZE,0);
bzero(buffer,BUFFER_SIZE);
length = recv(new_server_socket,buffer,BUFFER_SIZE,0);
printf("Server Recieve Data Failed!\n");
fprintf(stderr,"got: %s in %d\n",buffer,getpid());
close(new_server_socket);
else if(child_process_pid > 0)
close(new_server_socket);
#define HELLO_WORLD_SERVER_PORT 6666
void talk_to_server(char ** argv){
struct sockaddr_in client_addr;
bzero(&client_addr,sizeof(client_addr));
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = htons(INADDR_ANY);
client_addr.sin_port = htons(0);
int client_socket = socket(AF_INET,SOCK_STREAM,0);
printf("Create Socket Failed!\n");
if( bind(client_socket,(struct sockaddr*)&client_addr,sizeof(client_addr))){
printf("Client Bind Port Failed!\n");
struct sockaddr_in server_addr;
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family = AF_INET;
if(inet_aton(argv[1],&server_addr.sin_addr) == 0)
printf("Server IP Address Error!\n");
server_addr.sin_port = htons(HELLO_WORLD_SERVER_PORT);
socklen_t server_addr_length = sizeof(server_addr);
connect( client_socket, (struct sockaddr*)&server_addr,
server_addr_length) < 0 ) {
printf("Can Not Connect To %s!\n",argv[1]);
char buffer[BUFFER_SIZE];
bzero(buffer,BUFFER_SIZE);
int length = recv( client_socket, buffer,BUFFER_SIZE,0);
printf("Recieve Data From Server %s Failed!\n", argv[1]);
printf("From Server %s :\t%s",argv[1],buffer);
bzero(buffer,BUFFER_SIZE);
gethostname(name,sizeof(name));
send(client_socket,buffer,BUFFER_SIZE,0);
int main(int argc, char **argv){
printf("Usage: ./%s ServerIPAddress\n",argv[0]);
然后,用三个机器,一个跑server,两个跑client。先运行server,再分别跑两个client,结果如下:
Before Main Process listen.
After Main Process listen.
./con-client.o 192.168.66.136
From Server 192.168.66.136: Hello,World! From Server! 678
From Server 192.168.66.136: Hello,World! From Server! 680
./con-client.o 192.168.66.136
From Server 192.168.66.136: Hello,World! From Server! 679
From Server 192.168.66.136: Hello,World! From Server! 681
此外也可以发现,listen动作不阻塞,accept动作阻塞。
服务器端主进程每当捕获到一个客户端请求,就fork一个子进程,
由子进程用 new_server_socket来send 和 recv工作。
fork子进程后,工作完毕再消除的方法未必理想,今后有机会看看能否事先开一个进程池,来提升效率。
本文转自健哥的数据花园博客园博客,原文链接:http://www.cnblogs.com/gaojian/archive/2012/08/02/2618642.html,如需转载请自行联系原作者