windows socket编程:select 用法 例子

本文介绍了一个简单的TCP服务器实现过程,包括初始化WinSock、创建并配置监听套接字、设置地址复用选项、绑定套接字到指定端口、监听传入连接、使用select进行多客户端管理等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >



http://blog.youkuaiyun.com/zjsiva/article/details/5895087

服务器端:

  1. #include <stdio.h>    
  2. #include <string.h>    
  3. #include <WINSOCK2.H>    
  4.     
  5. #pragma comment(lib,"ws2_32.lib")    
  6.     
  7. #define INT_SERVER_PORT 5000    
  8. #define STR_SERVER_IP "127.0.0.1"    
  9. #define INT_DATABUFFER_SIZE 100    
  10.     
  11. void main(void)    
  12. {    
  13.     WORD dwVersion = MAKEWORD(2,2);    
  14.     WSAData wsaData;    
  15.     WSAStartup(WINSOCK_VERSION,&wsaData);    
  16.     
  17.     SOCKET sockServer = socket(AF_INET,SOCK_STREAM,0);    
  18.     if (INVALID_SOCKET == sockServer)    
  19.     {    
  20.         printf("Failed to create socket!\n");    
  21.         WSACleanup();    
  22.         return;    
  23.     }    
  24.     
  25.     sockaddr_in addrServer;    
  26.     memset(&addrServer,0,sizeof(sockaddr_in));    
  27.     addrServer.sin_family = AF_INET;    
  28.     addrServer.sin_port = htons(INT_SERVER_PORT);    
  29.     addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);    
  30.     //addrServer.sin_addr.s_addr = htonl(INADDR_ANY);    
  31.     
  32.     int iResult;    
  33.     
  34.     bool bReuseAddr=true;    
  35.     iResult=setsockopt(sockServer,SOL_SOCKET,SO_REUSEADDR,(char *)&bReuseAddr,sizeof(bReuseAddr));    
  36.     if(SOCKET_ERROR == iResult)    
  37.     {    
  38.         printf("Failed to set resueaddr socket!\n");    
  39.         WSACleanup();    
  40.         return;    
  41.     }    
  42.         
  43.     /*  
  44.     unsigned   long cmd = 1;   
  45.     iResult= ioctlsocket(sockServer,FIONBIO,&cmd); */    
  46.     
  47.     iResult = bind(sockServer,(sockaddr *)&addrServer,sizeof(addrServer));    
  48.     if (SOCKET_ERROR == iResult)    
  49.     {    
  50.         printf("Failed to bind address!\n");    
  51.         WSACleanup();    
  52.         return;    
  53.     }    
  54.     
  55.     if (0 != listen(sockServer,5))    
  56.     {    
  57.         printf("Failed to listen client!\n");    
  58.         WSACleanup();    
  59.         return;    
  60.     }    
  61.     
  62.     UINT i = 0;    
  63.     SOCKET sockAccept;    
  64.     sockaddr_in addrAccept;    
  65.     int iAcceptLen = sizeof(addrAccept);    
  66.     char szDataBuff[INT_DATABUFFER_SIZE];    
  67.     int iRecvSize;    
  68.         
  69.     sockaddr_in addrTemp;    
  70.     int iTempLen;    
  71.     
  72.     fd_set fd;    
  73.     FD_ZERO(&fd);    
  74.     FD_SET(sockServer,&fd);    
  75.     
  76.     /*  
  77.     timeval tm;  
  78.     tm.tv_sec = 0;  
  79.     tm.tv_usec = 1000;  
  80.     */    
  81.     printf("Start server...\n");    
  82.     while(1)    
  83.     {    
  84.         fd_set fdOld = fd;    
  85.         iResult = select(0,&fdOld,NULL,NULL,/*&tm*/NULL);    
  86.         if (0 <= iResult)    
  87.         {    
  88.             for(i = 0;i < fd.fd_count; i++)    
  89.             {    
  90.                 if (FD_ISSET(fd.fd_array[i],&fdOld))    
  91.                 {    
  92.                     //如果socket是服务器,则接收连接    
  93.                     if (fd.fd_array[i] == sockServer)    
  94.                     {    
  95.                         memset(&addrAccept,0,sizeof(addrTemp));    
  96.                         sockAccept = accept(sockServer,(sockaddr *)&addrAccept,&iAcceptLen);    
  97.                         if (INVALID_SOCKET != sockAccept)    
  98.                         {    
  99.                             FD_SET(sockAccept,&fd);    
  100.                             //FD_SET(sockAccept,&fdOld);    
  101.                             printf("%s:%d has connected server!\n",inet_ntoa(addrAccept.sin_addr),    
  102.                                 ntohs(addrAccept.sin_port));    
  103.                         }    
  104.                     }    
  105.                     else //非服务器,接收数据(因为fd是读数据集)    
  106.                     {    
  107.                         memset(szDataBuff,0,INT_DATABUFFER_SIZE);    
  108.                         iRecvSize = recv(fd.fd_array[i],szDataBuff,INT_DATABUFFER_SIZE,0);    
  109.                         memset(&addrTemp,0,sizeof(addrTemp));    
  110.                         iTempLen = sizeof(addrTemp);    
  111.                         getpeername(fd.fd_array[i],(sockaddr *)&addrTemp,&iTempLen);    
  112.                             
  113.                         if (SOCKET_ERROR == iRecvSize)    
  114.                         {    
  115.                             closesocket(fd.fd_array[i]);    
  116.                             FD_CLR(fd.fd_array[i],&fd);    
  117.                             i--;    
  118.                             printf("Failed to recv data ,%s:%d errorcode:%d.\n",    
  119.                                 inet_ntoa(addrTemp.sin_addr),ntohs(addrTemp.sin_port),WSAGetLastError());    
  120.                             continue;    
  121.                         }    
  122.     
  123.                         if (0 == iRecvSize)    
  124.                         {    
  125.                             //客户socket关闭    
  126.                             printf("%s:%d has closed!\n",inet_ntoa(addrTemp.sin_addr),    
  127.                                 ntohs(addrTemp.sin_port));    
  128.                                 
  129.                             closesocket(fd.fd_array[i]);    
  130.                             FD_CLR(fd.fd_array[i],&fd);    
  131.                             i--;        
  132.                         }    
  133.                             
  134.                         if (0 < iRecvSize)    
  135.                         {    
  136.                             //打印接收的数据    
  137.                             printf("recv %s:%d data:%s\n",inet_ntoa(addrTemp.sin_addr),    
  138.                                 ntohs(addrTemp.sin_port),szDataBuff);    
  139.                         }    
  140.                     }       
  141.                 }    
  142.             }    
  143.         }    
  144.         else if (SOCKET_ERROR == iResult)    
  145.         {    
  146.             //WSACleanup();     
  147.         //  printf("Faild to select sockt in server!\n");    
  148.             Sleep(100);    
  149.         }    
  150.     }    
  151.     WSACleanup();    
  152. }    
#include <stdio.h>  
#include <string.h>  
#include <WINSOCK2.H>  
  
#pragma comment(lib,"ws2_32.lib")  
  
#define INT_SERVER_PORT 5000  
#define STR_SERVER_IP "127.0.0.1"  
#define INT_DATABUFFER_SIZE 100  
  
void main(void)  
{  
    WORD dwVersion = MAKEWORD(2,2);  
    WSAData wsaData;  
    WSAStartup(WINSOCK_VERSION,&wsaData);  
  
    SOCKET sockServer = socket(AF_INET,SOCK_STREAM,0);  
    if (INVALID_SOCKET == sockServer)  
    {  
        printf("Failed to create socket!\n");  
        WSACleanup();  
        return;  
    }  
  
    sockaddr_in addrServer;  
    memset(&addrServer,0,sizeof(sockaddr_in));  
    addrServer.sin_family = AF_INET;  
    addrServer.sin_port = htons(INT_SERVER_PORT);  
    addrServer.sin_addr.S_un.S_addr = htonl(INADDR_ANY);  
    //addrServer.sin_addr.s_addr = htonl(INADDR_ANY);  
  
    int iResult;  
  
    bool bReuseAddr=true;  
    iResult=setsockopt(sockServer,SOL_SOCKET,SO_REUSEADDR,(char *)&bReuseAddr,sizeof(bReuseAddr));  
    if(SOCKET_ERROR == iResult)  
    {  
        printf("Failed to set resueaddr socket!\n");  
        WSACleanup();  
        return;  
    }  
      
    /* 
    unsigned   long cmd = 1;  
    iResult= ioctlsocket(sockServer,FIONBIO,&cmd); */  
  
    iResult = bind(sockServer,(sockaddr *)&addrServer,sizeof(addrServer));  
    if (SOCKET_ERROR == iResult)  
    {  
        printf("Failed to bind address!\n");  
        WSACleanup();  
        return;  
    }  
  
    if (0 != listen(sockServer,5))  
    {  
        printf("Failed to listen client!\n");  
        WSACleanup();  
        return;  
    }  
  
    UINT i = 0;  
    SOCKET sockAccept;  
    sockaddr_in addrAccept;  
    int iAcceptLen = sizeof(addrAccept);  
    char szDataBuff[INT_DATABUFFER_SIZE];  
    int iRecvSize;  
      
    sockaddr_in addrTemp;  
    int iTempLen;  
  
    fd_set fd;  
    FD_ZERO(&fd);  
    FD_SET(sockServer,&fd);  
  
    /* 
    timeval tm; 
    tm.tv_sec = 0; 
    tm.tv_usec = 1000; 
    */  
    printf("Start server...\n");  
    while(1)  
    {  
        fd_set fdOld = fd;  
        iResult = select(0,&fdOld,NULL,NULL,/*&tm*/NULL);  
        if (0 <= iResult)  
        {  
            for(i = 0;i < fd.fd_count; i++)  
            {  
                if (FD_ISSET(fd.fd_array[i],&fdOld))  
                {  
                    //如果socket是服务器,则接收连接  
                    if (fd.fd_array[i] == sockServer)  
                    {  
                        memset(&addrAccept,0,sizeof(addrTemp));  
                        sockAccept = accept(sockServer,(sockaddr *)&addrAccept,&iAcceptLen);  
                        if (INVALID_SOCKET != sockAccept)  
                        {  
                            FD_SET(sockAccept,&fd);  
                            //FD_SET(sockAccept,&fdOld);  
                            printf("%s:%d has connected server!\n",inet_ntoa(addrAccept.sin_addr),  
                                ntohs(addrAccept.sin_port));  
                        }  
                    }  
                    else //非服务器,接收数据(因为fd是读数据集)  
                    {  
                        memset(szDataBuff,0,INT_DATABUFFER_SIZE);  
                        iRecvSize = recv(fd.fd_array[i],szDataBuff,INT_DATABUFFER_SIZE,0);  
                        memset(&addrTemp,0,sizeof(addrTemp));  
                        iTempLen = sizeof(addrTemp);  
                        getpeername(fd.fd_array[i],(sockaddr *)&addrTemp,&iTempLen);  
                          
                        if (SOCKET_ERROR == iRecvSize)  
                        {  
                            closesocket(fd.fd_array[i]);  
                            FD_CLR(fd.fd_array[i],&fd);  
                            i--;  
                            printf("Failed to recv data ,%s:%d errorcode:%d.\n",  
                                inet_ntoa(addrTemp.sin_addr),ntohs(addrTemp.sin_port),WSAGetLastError());  
                            continue;  
                        }  
  
                        if (0 == iRecvSize)  
                        {  
                            //客户socket关闭  
                            printf("%s:%d has closed!\n",inet_ntoa(addrTemp.sin_addr),  
                                ntohs(addrTemp.sin_port));  
                              
                            closesocket(fd.fd_array[i]);  
                            FD_CLR(fd.fd_array[i],&fd);  
                            i--;      
                        }  
                          
                        if (0 < iRecvSize)  
                        {  
                            //打印接收的数据  
                            printf("recv %s:%d data:%s\n",inet_ntoa(addrTemp.sin_addr),  
                                ntohs(addrTemp.sin_port),szDataBuff);  
                        }  
                    }     
                }  
            }  
        }  
        else if (SOCKET_ERROR == iResult)  
        {  
            //WSACleanup();   
        //  printf("Faild to select sockt in server!\n");  
            Sleep(100);  
        }  
    }  
    WSACleanup();  
}  


客户端可以直接用nc,即netcat

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值