多大男性有性功能障:用select模式收发处理数据(跨平台)

来源:百度文库 编辑:偶看新闻 时间:2024/04/30 00:15:17

用select模式收发处理数据(跨平台)


   本Demo程序模拟C/S传输数据。采用select模式,分别实现了一个客户端小程序和服务端小程序。已在VC2005和Fedroa 13下测试通过。因时间有限,功能简单,欢迎交流,学习!

 

main.cpp

  1. #include "Sock.h"  
  2.   
  3. /* 
  4. * 传输数据格式 
  5. *  ___________ _____________ 
  6. * |           |             | 
  7. * | 32字节头   | 负载数据     | 
  8. * |___________|_____________| 
  9. * 其中32位头中: 
  10. * 第0个字节为数据包起始标志:0xCC 
  11. * 第1个字节为命令字 
  12. * 第4个字节为负载数据长度 
  13. * 其余字节填0 
  14. */  
  15.   
  16. int main(int argc, char* argv[])  
  17. {  
  18.     int nRet;  
  19.     Sock g_sock;  
  20.     char szBuf[1024];  
  21.   
  22.     //初始化Socket环境  
  23.     nRet = g_sock.StartUp();  
  24.     if (nRet < 0)  
  25.     {  
  26.         cout<
  27.         return 1;  
  28.     }  
  29.   
  30.     //客户端  
  31. #if defined(_CLIENT_)  
  32.   
  33.     cout<
  34.   
  35.     char ch;  
  36.     while (1)  
  37.     {  
  38.         cin>>ch;  
  39.         if ( ch == 's')  
  40.         {  
  41.             break;  
  42.         }  
  43.     }  
  44.   
  45.     g_sock.SetRemoteAddr(SERVER_IP, SERVER_PORT);  
  46.   
  47.     if (opMode_udp == g_sock.GetProtocol())  
  48.     {  
  49.         //创建并绑定本端Socket  
  50.         nRet = g_sock.CreateSock(CLIENT_IP, CLIENT_PORT);  
  51.         if (nRet < 0)  
  52.         {  
  53.             cout<
  54.             return 1;  
  55.         }  
  56.     }  
  57.     else if (opMode_tcp == g_sock.GetProtocol())  
  58.     {  
  59.         //创建本端Socket,并连接服务端  
  60.         nRet = g_sock.StartConnect(CLIENT_IP, CLIENT_PORT, 5000);  
  61.         if (nRet < 0)  
  62.         {  
  63.             cout<
  64.             return 1;  
  65.         }  
  66.     }  
  67.   
  68.     //向服务端发送登录请求  
  69.     memset(szBuf, 0, sizeof(szBuf));  
  70.     szBuf[0] = (char)0xCC;  
  71.     szBuf[1] = (char)0xA0;  
  72.     char *p = "Hello Server!";  
  73.     int nExtLen = strlen(p);  
  74.     memcpy(szBuf + 4, &nExtLen, sizeof(unsigned int));  
  75.     strcpy(szBuf + HEADER_SIZE, p);  
  76.     nRet = g_sock.SendData(szBuf, HEADER_SIZE + nExtLen);  
  77.     if (nRet < 0)  
  78.     {  
  79.         cout<
  80.     }  
  81.     else  
  82.     {  
  83.         cout<
  84.     }  
  85.   
  86.   
  87.     //接收来自服务端的请求回应,并处理  
  88.     nRet = g_sock.RecvData();  
  89.   
  90.     //服务端  
  91. #elif defined(_SERVER_)  
  92.       
  93.     //创建本端套接字,绑定,并开始侦听  
  94.     nRet = g_sock.StartListen(SERVER_IP, SERVER_PORT);  
  95.     if (nRet < 0)  
  96.     {  
  97.         cout<
  98.         return 1;  
  99.     }  
  100.   
  101.     g_sock.SetRemoteAddr(CLIENT_IP, CLIENT_PORT);  
  102.   
  103.     //接收来自客户端的请求,并进行应答处理  
  104.     nRet = g_sock.RecvData();  
  105.   
  106. #endif  
  107.   
  108. #ifdef WIN32  
  109.     system("pause");  
  110. #endif  
  111.   
  112.     //清理socket环境  
  113.     g_sock.CleanUp();  
  114.   
  115.     return 0;  
  116. }  


 

sock.h

  1. #ifndef _SOCK_H  
  2. #define _SOCK_H  
  3.   
  4. #ifdef WIN32  
  5.   
  6. #ifndef _WIN32_WINNT  
  7. #define _WIN32_WINNT 0x0400  
  8. #endif  
  9.   
  10. #define    WIN32_LEAN_AND_MEAN  
  11.   
  12. #include   
  13. #include   
  14.   
  15. #define EWOULDBLOCK             WSAEWOULDBLOCK  
  16. #define EINPROGRESS             WSAEINPROGRESS  
  17.   
  18. #pragma warning(disable:4996)  
  19.   
  20. #else  
  21.   
  22. #include   
  23. #include   
  24. #include   
  25. #include   
  26. #include   
  27. #include   
  28. #include   
  29. #include   
  30. #include   
  31. #include   
  32. #include   
  33. #include   
  34. #include   
  35. #include   
  36. #include   
  37. #include   
  38. #include   
  39.   
  40. #define EWOULDBLOCK EAGAIN  
  41.   
  42. #include   
  43.   
  44. #include   
  45. #include   
  46.   
  47. typedef int SOCKET;  
  48. #define INVALID_SOCKET -1  
  49. #define closesocket close   
  50.   
  51. #endif  
  52.   
  53. #include   
  54. using namespace std;  
  55.   
  56. typedef enum _opMode  
  57. {  
  58.     opMode_none = 0,  
  59.     opMode_tcp,  
  60.     opMode_udp  
  61. } opMode;  
  62.   
  63. #define HEADER_SIZE 32  
  64.   
  65. #define CLIENT_IP   "127.0.0.1"  
  66. #define SERVER_IP   "127.0.0.1"  
  67. #define CLIENT_PORT 5678  
  68. #define SERVER_PORT 5679  
  69.   
  70.   
  71. class Sock  
  72. {  
  73. public:  
  74.     Sock(void);  
  75.     ~Sock(void);  
  76.   
  77.     int SetRemoteAddr(const char* szIp, int nPort);  
  78.     int GetProtocol(){return m_nProtocol;}  
  79.   
  80.     int StartUp();  
  81.     int CleanUp();  
  82.   
  83.     int CreateSock(const char* szIp = NULL, int nPort = 0);  
  84.     int StartListen(const char* szIp, int nPort);  
  85.     int StartConnect(const char* szIp, int nPort, int nTimeOut);  
  86.   
  87.     int SendData(char *pszbuf,int nLength);  
  88.     int RecvData();  
  89.     int TcpRecv();  
  90.     int UdpRecv();  
  91.   
  92.     int DealData(char *pData, int nLength);  
  93.   
  94. private:  
  95.   
  96.     unsigned long   m_localIp;  
  97.     unsigned short  m_localPort;  
  98.     unsigned long   m_remoteIp;   
  99.     unsigned short  m_remotePort;  
  100.   
  101.     int             m_nProtocol;  
  102.     SOCKET          m_socket;  
  103.     SOCKET          m_clientSock;  
  104.   
  105.     int             m_recvBuffSize;  
  106.     int             m_sendBuffSize;  
  107.   
  108.     int             m_bExitRecv;  
  109. };  
  110.   
  111.   
  112. #endif  


Sock.cpp

  1. #include "Sock.h"  
  2.   
  3. Sock::Sock(void)  
  4. {  
  5.     m_remoteIp  = INADDR_ANY;  
  6.     m_remotePort= 0;  
  7.     m_localIp   = INADDR_ANY;  
  8.     m_localPort = 0;  
  9.     m_socket = INVALID_SOCKET;  
  10.     m_clientSock = INVALID_SOCKET;  
  11.   
  12.     m_recvBuffSize = 4 * 1024;  
  13.     m_sendBuffSize = 4 * 1024;  
  14.   
  15.     m_bExitRecv = false;  
  16.   
  17.     m_nProtocol = opMode_udp;  
  18. }  
  19.   
  20. Sock::~Sock(void)  
  21. {  
  22. }  
  23.   
  24. int Sock::SetRemoteAddr(const char* szIp, int nPort)  
  25. {  
  26.     m_remoteIp = inet_addr(szIp);  
  27.     m_remotePort = htons(nPort);  
  28.   
  29.     return 1;  
  30. }  
  31.   
  32. int Sock::StartUp()  
  33. {  
  34. #ifdef WIN32  
  35.     WSADATA wsa = {0};  
  36.     int ret = WSAStartup(MAKEWORD(2,2), &wsa);  
  37.     if (ret != 0)  
  38.     {  
  39.         return -1;  
  40.     }  
  41. #endif  
  42.     return 1;  
  43. }  
  44.   
  45. int Sock::CleanUp()  
  46. {  
  47. #ifdef WIN32  
  48.     if (WSACleanup() == SOCKET_ERROR)  
  49.     {  
  50.         return -1;  
  51.     }  
  52. #endif  
  53.     return 1;  
  54. }  
  55.   
  56. int Sock::CreateSock(const char* szIp, int nPort)  
  57. {  
  58.     if (m_socket != INVALID_SOCKET)  
  59.     {  
  60.         return -1;  
  61.     }  
  62.   
  63.     //创建套接字  
  64.     if (opMode_tcp == m_nProtocol)  
  65.     {  
  66.         m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);  
  67.     }  
  68.     else if (opMode_udp == m_nProtocol)  
  69.     {  
  70.         m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);  
  71.     }  
  72. #ifdef WIN32  
  73.     errno = WSAGetLastError();  
  74. #endif  
  75.     if (m_socket == INVALID_SOCKET)  
  76.     {  
  77.         return -1;  
  78.     }  
  79.   
  80.     int nBlock = 1; //设为非阻塞模式  
  81.     int nRet;  
  82. #ifdef WIN32  
  83.     nRet = ::ioctlsocket(m_socket,FIONBIO,(u_long FAR *)&nBlock);  
  84.     if (nRet == SOCKET_ERROR)   
  85.     {  
  86.         errno = ::WSAGetLastError();  
  87.         nRet = -1;  
  88.     }  
  89. #else  
  90.     nBlock = ::fcntl(m_socket, F_GETFL, 0);  
  91.     if (nBlock != -1)  
  92.     {  
  93.         nBlock |= O_NONBLOCK;  
  94.         nRet = ::fcntl(m_socket, F_SETFL, nBlock);  
  95.     }  
  96. #endif  
  97.     if ( -1 == nRet )  
  98.     {  
  99.         closesocket(m_socket);   
  100.         m_socket = INVALID_SOCKET;  
  101.         return -1;  
  102.     }  
  103.   
  104.     if (szIp == NULL)  
  105.     {  
  106.         m_localIp = INADDR_ANY;  
  107.     }  
  108.     else  
  109.     {  
  110.         m_localIp = inet_addr(szIp);  
  111.     }  
  112.   
  113.     m_localPort = htons(nPort);  
  114.   
  115.     //绑定套接字端口  
  116.     if (m_localPort != 0)  
  117.     {  
  118.         struct sockaddr_in local_addr;  
  119.         memset(&local_addr, 0, sizeof(struct sockaddr_in));  
  120.         local_addr.sin_family = AF_INET;  
  121.         local_addr.sin_port = m_localPort;  
  122.         local_addr.sin_addr.s_addr = m_localIp;  
  123.   
  124.         if (INVALID_SOCKET == bind(m_socket, (struct sockaddr *)&local_addr, sizeof(struct sockaddr)))  
  125.         {  
  126.             closesocket(m_socket);  
  127.             m_socket = INVALID_SOCKET;  
  128.             return -1;  
  129.         }  
  130.     }  
  131.     else if (opMode_udp == m_nProtocol)  
  132.     {  
  133.         //随机绑定  
  134.         struct sockaddr_in local_addr;  
  135.         memset(&local_addr, 0, sizeof(struct sockaddr_in));  
  136.         local_addr.sin_family = AF_INET;  
  137.   
  138.         if ( '\0' == szIp[0] )  
  139.         {  
  140.             local_addr.sin_addr.s_addr = htonl(INADDR_ANY);  
  141.         }  
  142.         else  
  143.         {  
  144.             local_addr.sin_addr.s_addr = inet_addr(szIp);  
  145.         }  
  146.   
  147.         int n;  
  148.         for (n = 0; n < 10000; n++)  
  149.         {  
  150.             local_addr.sin_port = htons(nPort + n);  
  151.             if ( 0 == bind(m_socket, (struct sockaddr*)&local_addr, sizeof(local_addr)) )  
  152.             {  
  153.                 break;  
  154.             }  
  155.         }  
  156.   
  157.         if (10000 == n)  
  158.         {  
  159.             closesocket(m_socket);  
  160.             m_socket = INVALID_SOCKET;  
  161.             return -1;  
  162.         }  
  163.   
  164.     }  
  165.   
  166.     //设置套接字接收和发送缓冲区大小  
  167.     if(m_recvBuffSize > 0)  
  168.         setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (char*)&m_recvBuffSize, sizeof(int));  
  169.     if(m_sendBuffSize > 0)  
  170.         setsockopt(m_socket, SOL_SOCKET, SO_SNDBUF, (char*)&m_sendBuffSize, sizeof(int));  
  171.   
  172.     return 1;  
  173.   
  174. }  
  175.   
  176. int Sock::StartListen(const char* szIp, int nPort)  
  177. {  
  178.     int nRet = CreateSock(szIp, nPort);  
  179.     if ( nRet < 0 )  
  180.     {  
  181.         return -1;  
  182.     }  
  183.   
  184.     if (opMode_tcp == m_nProtocol)  
  185.     {  
  186.         listen(m_socket,5);  
  187.     }  
  188.   
  189.     return 1;  
  190. }  
  191.   
  192. int Sock::StartConnect(const char* szIp, int nPort, int nTimeOut)  
  193. {  
  194.     int nRet = CreateSock(szIp, nPort);  
  195.     if (nRet < 0)  
  196.     {  
  197.         return -1;  
  198.     }  
  199.   
  200.     struct sockaddr_in remote_addr;  
  201.     memset(&remote_addr, 0, sizeof(remote_addr));  
  202.   
  203.     remote_addr.sin_family = AF_INET;  
  204.     remote_addr.sin_addr.s_addr = m_remoteIp;  
  205.     remote_addr.sin_port = m_remotePort;  
  206.   
  207.     //连接服务端  
  208.     nRet = connect(m_socket, (struct sockaddr *)&remote_addr, sizeof(struct sockaddr));  
  209. #ifdef WIN32  
  210.     if ( SOCKET_ERROR == nRet && (errno = WSAGetLastError()) == EWOULDBLOCK)  
  211.     {  
  212. #else  
  213.     if ( -1 == nRet && EINPROGRESS == errno )  
  214.     {  
  215.         errno = EWOULDBLOCK;   
  216. #endif  
  217.   
  218.         fd_set fdwrite;  
  219.         FD_ZERO(&fdwrite);  
  220.         FD_SET(m_socket,&fdwrite);  
  221.         timeval tv;  
  222.         tv.tv_sec = nTimeOut/1000;  
  223.         tv.tv_usec = nTimeOut%1000;  
  224.         nRet = select(m_socket + 1, NULL, &fdwrite, NULL, &tv);  
  225. #ifdef WIN32  
  226.         if ( SOCKET_ERROR == nRet )  
  227.         {  
  228.             errno = WSAGetLastError();  
  229.             closesocket(m_socket);  
  230.             m_socket = INVALID_SOCKET;  
  231.             return -1;  
  232.         }  
  233. #else  
  234.         if ( -1 == nRet )  
  235.         {  
  236.             closesocket(m_socket);  
  237.             m_socket = INVALID_SOCKET;  
  238.             return -1;  
  239.         }  
  240. #endif  
  241.         if ( 0 == nRet ) //超时  
  242.         {  
  243.             closesocket(m_socket);  
  244.             m_socket = INVALID_SOCKET;  
  245.             return -1;  
  246.         }  
  247.     }  
  248.     else  
  249.     {  
  250.         closesocket(m_socket);  
  251.         m_socket = INVALID_SOCKET;  
  252.         return -1;  
  253.     }  
  254.   
  255.     return 1;  
  256. }  
  257.   
  258. int Sock::SendData(char *pszbuf,int nLength)  
  259. {  
  260.     if (!pszbuf)  
  261.     {  
  262.         return -1;  
  263.     }  
  264.   
  265.     int nRet;  
  266.     if (opMode_tcp == m_nProtocol)  
  267.     {  
  268. #if defined(_CLIENT_)  
  269.         nRet = send(m_socket,pszbuf,nLength,0);  
  270. #elif defined(_SERVER_)  
  271.         nRet = send(m_clientSock,pszbuf,nLength,0);  
  272. #endif  
  273.     }  
  274.     else if (opMode_udp == m_nProtocol)  
  275.     {  
  276.         sockaddr_in remote_addr;  
  277.         remote_addr.sin_family = AF_INET;  
  278.         remote_addr.sin_addr.s_addr = m_remoteIp;  
  279.         remote_addr.sin_port = m_remotePort;  
  280.         nRet = sendto(m_socket,pszbuf,nLength,0,(sockaddr*)&remote_addr,sizeof(remote_addr));  
  281.     }  
  282.   
  283.     if (nRet != nLength)  
  284.     {  
  285.         cout<
  286.         return -1;  
  287.     }  
  288.     else  
  289.     {  
  290.         cout<
  291.     }  
  292.   
  293.     return 1;  
  294. }  
  295.   
  296. int Sock::RecvData()  
  297. {  
  298.     int nRet;  
  299.     if (opMode_udp == m_nProtocol)  
  300.     {  
  301.         nRet = UdpRecv();  
  302.     }  
  303.     else if (opMode_tcp == m_nProtocol)  
  304.     {  
  305.         nRet = TcpRecv();  
  306.     }  
  307.   
  308.     return 1;  
  309. }  
  310.   
  311. int Sock::TcpRecv()  
  312. {  
  313.     int fds,nRet;  
  314.     int nNeeRecvLen = 0,nRecvLen = 0, ntmpLen = 0;  
  315.     timeval tv;  
  316.     char szbuf[1024*4];  
  317.     int iTotal;  
  318.     fd_set fd_recv;  
  319.     FD_ZERO(&fd_recv);  
  320.     sockaddr_in addr;  
  321.     int iAddrSize = sizeof(addr);  
  322.     SOCKET tmpSock;  
  323.   
  324.     while (true)  
  325.     {  
  326.         if (m_bExitRecv)  
  327.         {  
  328.             break;  
  329.         }  
  330.   
  331.         tv.tv_sec = 0;  
  332.         tv.tv_usec = 100000;  
  333.         //memset(szbuf,0,sizeof(szbuf));  
  334.         fds = 0;  
  335.         FD_ZERO(&fd_recv);  
  336.         FD_SET(m_socket,&fd_recv);  
  337.         fds = m_socket;  
  338. #ifdef _SERVER_  
  339.         if (INVALID_SOCKET != m_clientSock)  
  340.         {  
  341.             FD_SET(m_clientSock,&fd_recv);  
  342.             if (m_clientSock > m_socket)  
  343.             {  
  344.                 fds = m_clientSock;  
  345.             }  
  346.         }  
  347. #endif  
  348.   
  349.         if ( fds <=0 )  
  350.         {  
  351. #ifdef WIN32  
  352.             Sleep(1);  
  353. #else  
  354.             sleep(1);  
  355. #endif  
  356.             continue;  
  357.         }  
  358.         iTotal = select(fds + 1, &fd_recv, 0, 0, &tv);  
  359.   
  360. #ifdef WIN32  
  361.         if ( SOCKET_ERROR == iTotal )  
  362.         {  
  363.             errno = WSAGetLastError();  
  364.             cout<
  365.         }  
  366. #else  
  367.         if ( -1 == iTotal )  
  368.         {  
  369.             cout<
  370.         }  
  371. #endif  
  372.         if ( iTotal == 0 ) //超时  
  373.         {  
  374.             continue;  
  375.         }  
  376.         if (FD_ISSET(m_socket,&fd_recv) || FD_ISSET(m_clientSock,&fd_recv))//接收  
  377.         {  
  378. #ifdef _SERVER_  
  379.             if (INVALID_SOCKET == m_clientSock)  
  380.             {  
  381.                 m_clientSock = accept(m_socket,(sockaddr*)&addr,  
  382. #if !defined(WIN32)  
  383.                     (socklen_t*)  
  384. #endif  
  385.                     &iAddrSize);  
  386.                 if ( INVALID_SOCKET == m_clientSock ) //错误  
  387.                 {  
  388. #ifdef WIN32  
  389.                     errno = WSAGetLastError();  
  390. #endif  
  391.                     cout<
  392.                 }  
  393.                 else  
  394.                 {  
  395.                     int nRet;  
  396.                     nRet = setsockopt(m_clientSock, SOL_SOCKET, SO_RCVBUF, (char*)&m_recvBuffSize, sizeof(m_recvBuffSize));  
  397.                     nRet = setsockopt(m_clientSock, SOL_SOCKET, SO_SNDBUF, (char*)&m_sendBuffSize, sizeof(m_sendBuffSize));  
  398.                     int nBlock = 1;  
  399. #ifdef WIN32  
  400.                     nRet = ::ioctlsocket(m_clientSock,FIONBIO,(u_long FAR *)&nBlock);  
  401.                     if (nRet == SOCKET_ERROR)   
  402.                     {  
  403.                         errno = ::WSAGetLastError();  
  404.                         nRet = -1;  
  405.                     }  
  406. #else  
  407.                     nBlock = ::fcntl(m_clientSock, F_GETFL, 0);  
  408.                     if (nBlock != -1)  
  409.                     {  
  410.                         nBlock |= O_NONBLOCK;  
  411.                         nRet = ::fcntl(m_clientSock, F_SETFL, nBlock);  
  412.                     }  
  413. #endif  
  414.                     if ( -1 == nRet )  
  415.                     {  
  416.                         cout<
  417.                     }  
  418.                 }  
  419.                 continue;  
  420.             }  
  421.             else  
  422.             {  
  423.                 tmpSock = m_clientSock;  
  424.             }  
  425. #else  
  426.         tmpSock = m_socket;  
  427. #endif  
  428.   
  429.         if ( 0 == nNeeRecvLen ) //接收消息32位头  
  430.         {  
  431.             nNeeRecvLen = HEADER_SIZE;  
  432.             nRecvLen = recv(tmpSock, szbuf, nNeeRecvLen, 0);  
  433. #ifdef WIN32  
  434.             if ( SOCKET_ERROR == nRecvLen )  
  435.             {  
  436.                 errno = WSAGetLastError();  
  437.                 if ( EWOULDBLOCK == errno )  
  438.                 {  
  439. #else  
  440.             if ( -1 == nRecvLen )  
  441.             {  
  442.                 if ( EAGAIN == errno )  
  443.                 {  
  444.                     errno = EWOULDBLOCK;  
  445. #endif  
  446.                 }  
  447.                 else   
  448.                 {  
  449.                     cout<
  450.                 }  
  451.               
  452.             }  
  453.             else if ( nRecvLen == 0 ) //套接字关闭  
  454.             {  
  455.                 continue;  
  456.             }  
  457.             else  
  458.             {  
  459.                 int nExtLen = (unsigned int)szbuf[4];  
  460.                 if (nExtLen > 0)  
  461.                 {  
  462.                     nNeeRecvLen = nExtLen;  
  463.                     ntmpLen = nRecvLen;  
  464.                 }  
  465.             }  
  466.         }  
  467.         else //接收消息扩展数据  
  468.         {  
  469.             nRecvLen = recv(tmpSock, szbuf+ntmpLen, nNeeRecvLen, 0);  
  470. #ifdef WIN32  
  471.             if ( SOCKET_ERROR == nRecvLen )  
  472.             {  
  473.                 errno = WSAGetLastError();  
  474.                 if ( EWOULDBLOCK == errno )  
  475.                 {  
  476. #else  
  477.             if ( -1 == nRecvLen )  
  478.             {  
  479.                 if ( EAGAIN == errno )  
  480.                 {  
  481.                     errno = EWOULDBLOCK;  
  482. #endif  
  483.                 }  
  484.                 else   
  485.                 {  
  486.                     cout<
  487.                 }  
  488.   
  489.             }  
  490.             else if ( nRecvLen == 0 ) //套接字关闭  
  491.             {  
  492.                 continue;  
  493.             }  
  494.             else  
  495.             {  
  496.                 if (nNeeRecvLen == nRecvLen)  
  497.                 {  
  498.                     szbuf[nRecvLen] = '\0';  
  499.                     //处理数据  
  500.                     DealData(szbuf, nRecvLen+ntmpLen);  
  501.                     nNeeRecvLen = 0;  
  502.                     ntmpLen = 0;  
  503.                 }  
  504.             }  
  505.         }  
  506.   
  507.         }  
  508.   
  509.     }  
  510.   
  511.     if (m_socket)  
  512.     {  
  513.         closesocket(m_socket);  
  514.         m_socket = INVALID_SOCKET;  
  515.     }  
  516.     if (m_clientSock)  
  517.     {  
  518.         closesocket(m_clientSock);  
  519.         m_clientSock = INVALID_SOCKET;  
  520.     }  
  521.       
  522.     return 1;  
  523. }  
  524.   
  525. int Sock::UdpRecv()  
  526. {  
  527.     int fds,nRet;  
  528.     timeval tv;  
  529.     char szbuf[1024*4];  
  530.     int iTotal;  
  531.     fd_set fd_recv;  
  532.     FD_ZERO(&fd_recv);  
  533.     sockaddr_in addr;  
  534.     int iAddrSize = sizeof(addr);  
  535.   
  536.     while (true)  
  537.     {  
  538.         if (m_bExitRecv)  
  539.         {  
  540.             break;  
  541.         }  
  542.   
  543.         tv.tv_sec = 0;  
  544.         tv.tv_usec = 100000;  
  545.         memset(szbuf,0,sizeof(szbuf));  
  546.         fds = 0;  
  547.         FD_ZERO(&fd_recv);  
  548.         FD_SET(m_socket,&fd_recv);  
  549.         fds = m_socket;  
  550.   
  551.         if ( fds <=0 )  
  552.         {  
  553. #ifdef WIN32  
  554.             Sleep(1);  
  555. #else  
  556.             sleep(1);  
  557. #endif  
  558.             continue;  
  559.         }  
  560.         iTotal = select(fds + 1, &fd_recv, 0, 0, &tv);  
  561.   
  562. #ifdef WIN32  
  563.         if ( SOCKET_ERROR == iTotal )  
  564.         {  
  565.             errno = WSAGetLastError();  
  566.             cout<
  567.         }  
  568. #else  
  569.         if ( -1 == iTotal )  
  570.         {  
  571.             cout<
  572.         }  
  573. #endif  
  574.         if ( iTotal == 0 ) //超时  
  575.         {  
  576.             continue;  
  577.         }  
  578.   
  579.         if ( FD_ISSET(m_socket,&fd_recv) )//接收  
  580.         {  
  581.             bool bCanRecv = true;  
  582.             while ( bCanRecv )  
  583.             {  
  584.               
  585.                 iAddrSize = sizeof(addr);  
  586.                 nRet = recvfrom(m_socket,szbuf,sizeof(szbuf),0,  
  587.                     (struct sockaddr*)&addr,  
  588. #if !defined(WIN32)  
  589.                     (socklen_t*)  
  590. #endif  
  591.                     &iAddrSize);  
  592. #ifdef WIN32  
  593.                 if ( SOCKET_ERROR == nRet )  
  594.                 {  
  595.                     errno = WSAGetLastError();  
  596.                     if ( EWOULDBLOCK == errno )  
  597.                     {  
  598. #else  
  599.                 if ( -1 == nRet )  
  600.                 {  
  601.                     if ( EAGAIN == errno )  
  602.                     {  
  603.                         errno = EWOULDBLOCK;  
  604. #endif  
  605.                     }  
  606.                     else //error  
  607.                     {  
  608.                         cout<
  609.                     }  
  610.                       
  611.                     bCanRecv = false;  
  612.                 }  
  613.                 else  
  614.                 {  
  615.                     //处理数据  
  616.                     DealData(szbuf, nRet);  
  617.                 }  
  618.             }  
  619.         }  
  620.     }  
  621.   
  622.     if (m_socket)  
  623.     {  
  624.         closesocket(m_socket);  
  625.         m_socket = INVALID_SOCKET;  
  626.     }  
  627.   
  628.     return 1;  
  629. }  
  630.   
  631.   
  632. int Sock::DealData(char *pData, int nLength)  
  633. {  
  634.     int nExtLen = 0;  
  635.     char szBuf[1024];  
  636.     memset(szBuf, 0, sizeof(szBuf));  
  637.     if (0xA0 == (unsigned char)pData[1])//服务端收到来自客户端的登录请求  
  638.     {  
  639.         nExtLen = (unsigned int)pData[4];  
  640.         memcpy(szBuf, pData+HEADER_SIZE, nExtLen);  
  641.         cout<
  642.   
  643.         memset(szBuf,0,sizeof(szBuf));  
  644.         szBuf[0] = (char)0xCC;  
  645.         szBuf[1] = (char)0xA1; //登录请求应答  
  646.         char *p = "Hello client!";  
  647.         nExtLen = strlen(p);  
  648.         memcpy(szBuf + 4, &nExtLen, sizeof(unsigned int));  
  649.         strcpy(szBuf + HEADER_SIZE, p);  
  650.         SendData(szBuf, HEADER_SIZE + nExtLen);  
  651.     }  
  652.     else if (0xA1 == (unsigned char)pData[1])//客户端收到来自服务端的登录请求应答  
  653.     {  
  654.         nExtLen = (unsigned int)pData[4];  
  655.         memcpy(szBuf, pData+HEADER_SIZE, nExtLen);  
  656.         cout<
  657.   
  658.         memset(szBuf,0,sizeof(szBuf));  
  659.         szBuf[0] = (char)0xCC; //发送退出请求  
  660.         szBuf[1] = (char)0xB0;  
  661.         char *p = "Hello Server, exit now";  
  662.         nExtLen = strlen(p);  
  663.         memcpy(szBuf + 4, &nExtLen, sizeof(unsigned int));  
  664.         strcpy(szBuf + HEADER_SIZE, p);  
  665.         SendData(szBuf, HEADER_SIZE + nExtLen);  
  666.   
  667.         m_bExitRecv = true;//本端退出  
  668.     }  
  669.     else if (0xB0 == (unsigned char)pData[1]) //服务端收到来自客户端的退出请求  
  670.     {  
  671.         m_bExitRecv = true;//服务端退出  
  672.     }  
  673.   
  674.     return 1;  
  675. }  


下边是Win32和Linux上的截图