Linux编程之服务器与客户端的socket通讯机制

       
       
在Linux中,服务器与客户端通过套接字来完成通讯。本文主要讲述的是在实际项目编程中,如何启动一个服务器来应对多个客户端的连接以及服务器和客户端各自采用select的意义。服务器:连接一个客户端则创建一个线程与该客户端通讯。客户端:连接服务器。具体过程如下:
服务器:

1、创建监听套接字

2、监听套接字绑定端口

3、服务器循环监听客户端的连接

4、如果一个客户端连接到服务器,服务器就创建该客户端的连接套接字,创建一个线程与该客户端通讯。(5-8是新的线程里执行的操作)


5、select获取包含内容的文件描述符(如果连接套接字里有内容,则被select获取)

6、读取套接字内容(根据内容执行不同的操作)

7、向套接字里写内容

8、断开连接,关闭连接套接字。


9、关闭监听套接字,退出服务器。


客户端:

1、创建套接字

2、连接服务器

3、select

4、读取内容(套接字或终端输入的内容)

5、写内容到套接字

6、关闭套接字,断开连接。


具体代码如下:

server.c

#include 
        
        
         
         
#include 
         
         
          
          
#include 
          
          
           
           
#include 
           
           
            
            
#include 
            
            
              #include 
             
               #include 
              
                #include 
               
                 void clientService(int *pconnect_fd); void startServer(); int main(int argc, char **argv) { startServer(); return 0; } void startServer() { pthread_t pthread_id[10]; int pthread_id_i = 0; char buffer[20] = {0}; int listen_fd, connect_fd; struct sockaddr_in server_addr, client_addr; unsigned short port_num = 0x8888; socklen_t sin_size; fd_set read_set; printf("Hello, welcome to my server !\n"); listen_fd = socket(AF_INET, SOCK_STREAM, 0); if(-1 == listen_fd) { printf("socket fail ! \n"); return ; } printf("socket ok ! The listen_fd is %d !\n", listen_fd); bzero(&server_addr, sizeof(struct sockaddr_in)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(port_num); if(-1 == bind(listen_fd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr))) { printf("bind fail !\n"); close(listen_fd); return ; } printf("bind ok !\n"); if(-1 == listen(listen_fd, 2)) { printf("listen fail !\n"); close(listen_fd); return ; } printf("listen ok !\n"); while(1) { FD_ZERO(&read_set); FD_SET(listen_fd, &read_set); FD_SET(0, &read_set); if(select(listen_fd+1, &read_set, NULL, NULL, 0) < 0) { printf("fail to select !\n"); continue; } if(FD_ISSET(listen_fd, &read_set)) { sin_size = sizeof(struct sockaddr_in); connect_fd = accept(listen_fd, (struct sockaddr *)(&client_addr), &sin_size); if(connect_fd < 0) { continue; } printf("accept ok ! The connect_fd is %d !\n", connect_fd); if(pthread_id_i >= 10) { printf("the source is over !\n"); close(connect_fd); close(listen_fd); return ; } pthread_create(&pthread_id[pthread_id_i++], NULL, (void *)clientService, &connect_fd); } if(FD_ISSET(0, &read_set)) { scanf("%s", buffer); if(strcmp(buffer, "q") == 0) { close(listen_fd); return ; } } } close(listen_fd); } void clientService(int *pconnect_fd) { int connect_fd = *pconnect_fd; char buffer[1024]; int read_len = 0; fd_set read_set; while(1) { FD_ZERO(&read_set); FD_SET(connect_fd, &read_set); if(select(connect_fd+1, &read_set, NULL, NULL, 0) < 0) { printf("fail to select !\n"); continue; } if(FD_ISSET(connect_fd, &read_set)) { if((read_len = read(connect_fd, buffer, 1024)) <= 0) { printf("read data fail !\n"); close(connect_fd); return ; } buffer[read_len] = '\0'; printf("read_len = %d, buffer : %s\n", read_len, buffer); if(-1 == write(connect_fd, buffer, strlen(buffer))) { printf("write fail !\n"); close(connect_fd); return ; } printf("write ok !\n"); } } close(connect_fd); } 
                
               
              
            
           
           
          
          
         
         
        
        

client.c

#include 
        
        
         
         
#include 
         
         
          
          
#include 
          
          
           
           
#include 
           
           
            
            
#include 
            
            
              #include 
             
               #include 
              
                #include 
               
                 int main(int argc, char **argv) { int client_socket_fd; int read_len; char buffer[1024] = {0}; fd_set read_set; struct sockaddr_in server_addr; unsigned short port_num = 0x8888; printf("Hello, welcome to client !\n"); client_socket_fd = socket(AF_INET, SOCK_STREAM, 0); if(-1 == client_socket_fd) { printf("socket fail !\n"); return -1; } printf("socket ok ! The client_socket_fd is %d !\n", client_socket_fd); bzero(&server_addr, sizeof(struct sockaddr_in)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); server_addr.sin_port = htons(port_num); if(-1 == connect(client_socket_fd, (struct sockaddr *)(&server_addr), sizeof(struct sockaddr))) { printf("connect fail !\n"); close(client_socket_fd); return -1; } printf("connect ok !\n"); while(1) { FD_ZERO(&read_set); FD_SET(client_socket_fd, &read_set); FD_SET(0, &read_set); if(select(client_socket_fd+1, &read_set, NULL, NULL, 0) <= 0) { printf("fail to select !\n"); close(client_socket_fd); return -1; } if(FD_ISSET(client_socket_fd, &read_set)) { if((read_len = read(client_socket_fd, buffer,1024)) <= 0) { printf("read data fail !\n"); close(client_socket_fd); return -1; } buffer[read_len] = '\0'; printf("read ok ! I have received a string : %s\n", buffer); } if(FD_ISSET(0, &read_set)) { scanf("%s", buffer); if(-1 == write(client_socket_fd, buffer, strlen(buffer))) { printf("write data fail !\n"); close(client_socket_fd); return -1; } if(strcmp(buffer, "q") == 0) { close(client_socket_fd); return 0; } } } close(client_socket_fd); return 0; } 
                
               
              
            
           
           
          
          
         
         
        
        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值