TCP Socket编程(非阻塞模式)(C++)

来源:互联网 发布:遗传算法c语言程序 编辑:程序博客网 时间:2024/06/06 12:45

代码来源:《Windows网络编程》(罗莉琴,詹祖桥 主编)(如造成任何不便,请联系我删除)

服务器:

[cpp] view plain copy
  1. // TcpServer.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include <winsock2.h>  
  6. #include <iostream>  
  7.   
  8. #pragma comment(lib,"ws2_32.lib")  
  9.   
  10. #define BUF_SIZE 64  
  11.   
  12. int _tmain(int argc, _TCHAR* argv[])  
  13. {  
  14.     WSADATA wsd;  
  15.     SOCKET sServer;  
  16.     SOCKET sClient;  
  17.     int retVal;  
  18.     char buf[BUF_SIZE];  
  19.   
  20.     //初始化Socket  
  21.     if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)  
  22.     {  
  23.         printf("WSAStartup failed!\n");  
  24.         return -1;  
  25.     }  
  26.     //创建用于监听的Socket  
  27.     sServer = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);  
  28.     if (INVALID_SOCKET == sServer)  
  29.     {  
  30.         printf("socket failed!\n");  
  31.         WSACleanup();  
  32.         return -1;  
  33.     }  
  34.     //设置Socket为非阻塞模式  
  35.     int iMode = 1;  
  36.     retVal = ioctlsocket(sServer,FIONBIO,(u_long FAR*)&iMode);  
  37.     if (retVal == SOCKET_ERROR)  
  38.     {  
  39.         printf("ioctlsocket failed!\n");  
  40.         WSACleanup();  
  41.         return -1;  
  42.     }  
  43.     //设置服务器Socket地址  
  44.     sockaddr_in addrServ;  
  45.     addrServ.sin_family = AF_INET;  
  46.     addrServ.sin_port = htons(9990);  
  47.     addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);  
  48.     //绑定Socket Server到本地地址  
  49.     retVal = bind(sServer,(const struct sockaddr*)&addrServ,sizeof(sockaddr_in));  
  50.     if (retVal == SOCKET_ERROR)  
  51.     {  
  52.         printf("bind failed!\n");  
  53.         closesocket(sServer);  
  54.         WSACleanup();  
  55.         return -1;  
  56.     }  
  57.     //监听  
  58.     retVal = listen(sServer,1);  
  59.     if (retVal == SOCKET_ERROR)  
  60.     {  
  61.         printf("listen failed!\n");  
  62.         closesocket(sServer);  
  63.         WSACleanup();  
  64.         return -1;  
  65.     }  
  66.     //接受客户请求  
  67.     printf("TCP Server start...\n");  
  68.     sockaddr_in addrClient;  
  69.     int addrClientlen = sizeof(addrClient);  
  70.     //循环等待  
  71.     while (true)  
  72.     {  
  73.         sClient = accept(sServer,(sockaddr FAR*)&addrClient,&addrClientlen);  
  74.         if (INVALID_SOCKET == sClient)  
  75.         {  
  76.             int err = WSAGetLastError();  
  77.             if (err == WSAEWOULDBLOCK)  
  78.             {  
  79.                 Sleep(100);  
  80.                 continue;  
  81.             }  
  82.             else  
  83.             {  
  84.                 printf("accept failed!\n");  
  85.                 closesocket(sServer);  
  86.                 WSACleanup();  
  87.                 return -1;  
  88.             }         
  89.         }  
  90.         break;  
  91.   
  92.     }  
  93.     //循环接受客户端的数据,直到客户端发送quit命令后退出  
  94.     while (true)  
  95.     {  
  96.         ZeroMemory(buf,BUF_SIZE);  
  97.         retVal = recv(sClient,buf,BUFSIZ,0);  
  98.         if (SOCKET_ERROR == retVal)  
  99.         {  
  100.             int err = WSAGetLastError();  
  101.             if (err == WSAEWOULDBLOCK)  
  102.             {  
  103.                 Sleep(100);  
  104.                 continue;  
  105.             }  
  106.             else if (err == WSAETIMEDOUT || err == WSAENETDOWN)  
  107.             {  
  108.                 printf("recv failed!\n");  
  109.                 closesocket(sServer);  
  110.                 closesocket(sClient);  
  111.                 WSACleanup();  
  112.                 return -1;  
  113.             }  
  114.         }  
  115.         //获取系统时间  
  116.         SYSTEMTIME st;  
  117.         GetLocalTime(&st);  
  118.         char sDateTime[30];  
  119.         sprintf_s(sDateTime, "%4d-%2d-%2d %2d:%2d:%2d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);  
  120.         //打印输出信息  
  121.         printf("%s,Recv From Client [%s:%d]:%s\n",sDateTime,inet_ntoa(addrClient.sin_addr),addrClient.sin_port,buf);  
  122.         //如果客户端发送“quit”字符串,则服务器退出  
  123.         if (strcmp(buf, "quit") == 0)  
  124.         {  
  125.             retVal = send(sClient,"quit",strlen("quit"),0);  
  126.             break;  
  127.         }  
  128.         else  
  129.         {  
  130.             char msg[BUF_SIZE];  
  131.             sprintf_s(msg,"Message received - %s",buf);  
  132.             while (true)  
  133.             {  
  134.                 retVal = send(sClient,msg,strlen(msg),0);  
  135.                 if (SOCKET_ERROR == retVal)  
  136.                 {  
  137.                     int err = WSAGetLastError();  
  138.                     if (err == WSAEWOULDBLOCK)  
  139.                     {  
  140.                         Sleep(100);  
  141.                         continue;  
  142.                     }  
  143.                     else  
  144.                     {  
  145.                         printf("send failed!\n");  
  146.                         closesocket(sServer);  
  147.                         closesocket(sClient);  
  148.                         WSACleanup();  
  149.                         return -1;  
  150.                     }  
  151.                       
  152.                 }  
  153.                 break;  
  154.             }  
  155.         }  
  156.     }  
  157.       
  158.     //释放Socket  
  159.     closesocket(sServer);  
  160.     closesocket(sClient);  
  161.     WSACleanup();  
  162.   
  163.     system("pause");  
  164.     return 0;  
  165. }  

客户端:

[cpp] view plain copy
  1. // TcpClient.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include <winsock2.h>  
  6. #include <string>  
  7. #include <iostream>  
  8.   
  9. #pragma comment(lib,"ws2_32.lib")  
  10. #define BUF_SIZE 64  
  11.   
  12.   
  13. int _tmain(int argc, _TCHAR* argv[])  
  14. {  
  15.     WSADATA wsd;  
  16.     SOCKET sHost;  
  17.     SOCKADDR_IN servAddr;  
  18.     char buf[BUF_SIZE];  
  19.     int retVal;  
  20.     //初始化Socket  
  21.     if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)  
  22.     {  
  23.         printf("WSAStartup failed!\n");  
  24.         return -1;  
  25.     }  
  26.     //创建Socket  
  27.     sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
  28.     if (INVALID_SOCKET == sHost)  
  29.     {  
  30.         printf("socket failed!\n");  
  31.         WSACleanup();  
  32.         return -1;  
  33.     }  
  34.     //设置Socket为非阻塞模式  
  35.     int iMode = 1;  
  36.     retVal = ioctlsocket(sHost, FIONBIO, (u_long FAR*)&iMode);  
  37.     if (retVal == SOCKET_ERROR)  
  38.     {  
  39.         printf("ioctlsocket failed!\n");  
  40.         WSACleanup();  
  41.         return -1;  
  42.     }  
  43.     //设置服务器Socket地址  
  44.     servAddr.sin_family = AF_INET;  
  45.     servAddr.sin_port = htons(9990);  
  46.     servAddr.sin_addr.S_un.S_addr = inet_addr("ip地址");//htonl(INADDR_ANY);  
  47.       
  48.     int sServerAddlen = sizeof(servAddr);  
  49.   
  50.     //连接到服务器  
  51.     while (true)  
  52.     {  
  53.         retVal = connect(sHost,(LPSOCKADDR)&servAddr,sizeof(servAddr));  
  54.         if (SOCKET_ERROR == retVal)  
  55.         {  
  56.             int err = WSAGetLastError();  
  57.             if (err == WSAEWOULDBLOCK || err == WSAEINVAL)  
  58.             {  
  59.                 Sleep(500);  
  60.                 continue;  
  61.             }  
  62.             else if (err == WSAEISCONN)  
  63.             {  
  64.                 break;  
  65.             }  
  66.             else  
  67.             {  
  68.                 printf("connection failed!\n");  
  69.                 closesocket(sHost);  
  70.                 WSACleanup();  
  71.                 return -1;  
  72.             }  
  73.         }  
  74.     }  
  75.   
  76.     //收发数据  
  77.     while (true)  
  78.     {  
  79.         printf("Please input a string to send:");  
  80.         std::string str;  
  81.         std::getline(std::cin,str);  
  82.         ZeroMemory(buf,BUF_SIZE);  
  83.         strcpy_s(buf,str.c_str());  
  84.         while (true)  
  85.         {  
  86.             retVal = send(sHost,buf,strlen(buf),0);  
  87.             if (SOCKET_ERROR == retVal)  
  88.             {  
  89.                 int err = WSAGetLastError();  
  90.                 if (err == WSAEWOULDBLOCK)  
  91.                 {  
  92.                     Sleep(500);  
  93.                     continue;  
  94.                 }  
  95.                 else  
  96.                 {  
  97.                     printf("send failed!\n");  
  98.                     closesocket(sHost);  
  99.                     WSACleanup();  
  100.                     return -1;  
  101.                 }  
  102.             }  
  103.             break;  
  104.   
  105.         }  
  106.           
  107.         while (true)  
  108.         {  
  109.             ZeroMemory(buf,BUF_SIZE);  
  110.             retVal = recv(sHost,buf,sizeof(buf)+1,0);  
  111.             if (SOCKET_ERROR == retVal)  
  112.             {  
  113.                 int err = WSAGetLastError();  
  114.                 if (err == WSAEWOULDBLOCK)  
  115.                 {  
  116.                     Sleep(100);  
  117.                     printf("waiting back msg!\n");  
  118.                     continue;  
  119.                 }  
  120.                 else if (err == WSAETIMEDOUT || err == WSAENETDOWN)  
  121.                 {  
  122.                     printf("recv failed!\n");  
  123.                     closesocket(sHost);  
  124.                     WSACleanup();  
  125.                     return -1;  
  126.                 }  
  127.                 break;  
  128.             }  
  129.             break;  
  130.               
  131.         }  
  132.         printf("Recv From Server:%s\n",buf);  
  133.         if (strcmp(buf, "quit") == 0)  
  134.         {  
  135.             printf("quit!\n");  
  136.             break;  
  137.         }  
  138.     }  
  139.   
  140.     closesocket(sHost);  
  141.     WSACleanup();  
  142.     system("pause");  
  143.   
  144.     return 0;  
  145. }  
原创粉丝点击