本文主要给大家提供一个Tcp Server的源码例子,各源码所在的文件名已在注释中标出。

C++代码
  1. //Filename: SockClass.cpp  
  2.   
  3. #include "SockClass.hpp"  
  4.   
  5. //sockClass  
  6.   
  7. namespace sockClass  
  8. {  
  9. void error_info(const char* s)  
  10. {  
  11.     std::cerr << s << std::endl;  
  12.     throw WSAGetLastError();  
  13. }  
  14. }  
  15.   
  16. //class WinsockAPI  
  17.   
  18. WinsockAPI::WinsockAPI(int low_byte, int high_byte)  
  19. {  
  20.     const WORD wVersionRequested = MAKEWORD(low_byte, high_byte);  
  21.     int wsa_startup_err = WSAStartup(wVersionRequested, &wsaData);  
  22.     if (wsa_startup_err != 0) {  
  23.         std::cerr << "WSAStartup() failed." << std::endl;  
  24.         throw wsa_startup_err;  
  25.     }  
  26. }  
  27.   
  28. WinsockAPI::~WinsockAPI()  
  29. {  
  30.     WSACleanup();  
  31. }  
  32.   
  33. void WinsockAPI::showVersion() const  
  34. {  
  35.     std::cout    << "The version of Winsock.dll is "   
  36.                 << int(LOBYTE(wsaData.wVersion))   
  37.                 << "."   
  38.                 << int(HIBYTE(wsaData.wVersion))   
  39.                 << "."   
  40.                 << std::endl;  
  41.     return;  
  42. }  
  43.   
  44. //class BaseSock  
  45.   
  46. BaseSock::BaseSock():  
  47. sockFD(-1)  
  48. {}  
  49.   
  50. BaseSock::~BaseSock()  
  51. {}  
  52.   
  53. const int& BaseSock::showSockFD() const  
  54. {  
  55.     return sockFD;  
  56. }  
  57.   
  58. //class TCPListenSock  
  59.   
  60. TCPListenSock::TCPListenSock(unsigned short listen_port)  
  61. {  
  62.     sockFD = socket(PF_INET,  
  63.                     SOCK_STREAM,  
  64.                     IPPROTO_TCP);  
  65.     if (sockFD < 0) {  
  66.         sockClass::error_info("socket() failed.");  
  67.     }  
  68.     memset(&listenSockAddr, 0, sizeof(listenSockAddr));  
  69.     listenSockAddr.sin_family = AF_INET;  
  70.     listenSockAddr.sin_addr.s_addr = htonl(INADDR_ANY);  
  71.     listenSockAddr.sin_port = htons(listen_port);  
  72.     if (bind(    sockFD,  
  73.                 (sockaddr*)&listenSockAddr,  
  74.                 sizeof(listenSockAddr)) < 0) {  
  75.         sockClass::error_info("bind() failed.");  
  76.     }  
  77. }  
  78.   
  79. TCPListenSock::~TCPListenSock()  
  80. {  
  81.     closesocket(sockFD);  
  82. }  
  83.   
  84. void TCPListenSock::TCPListen(  
  85.                         int max_connection_requests) const  
  86. {  
  87.     if (listen(    sockFD,  
  88.                 max_connection_requests) < 0) {  
  89.         sockClass::error_info("listen() failed.");  
  90.     }  
  91. }  
  92.   
  93. //class TCPServerSock  
  94.   
  95. TCPServerSock::TCPServerSock(  
  96.                 const TCPListenSock& listen_sock,  
  97.                 int pre_buffer_size):  
  98. preBufferSize(pre_buffer_size),  
  99. preReceivedLength(0)  
  100. {  
  101.     preBuffer = new char[preBufferSize];  
  102.   
  103.     int clientSockAddrLen = sizeof(clientSockAddr);  
  104.     sockFD = accept(    listen_sock.showSockFD(),  
  105.                         (sockaddr*)&clientSockAddr,  
  106.                         &clientSockAddrLen);  
  107.     if (sockFD < 0) {  
  108.         sockClass::error_info("accept() failed.");  
  109.     }  
  110.     std::cout    << "Client (IP: "  
  111.                 << inet_ntoa(clientSockAddr.sin_addr)  
  112.                 << ") conneted." << std::endl;  
  113. }  
  114.   
  115. TCPServerSock::~TCPServerSock()  
  116. {  
  117.     delete [] preBuffer;  
  118.     closesocket(sockFD);  
  119. }  
  120.   
  121. int TCPServerSock::TCPReceive() const  
  122. {  
  123.     preReceivedLength = recv(    sockFD,  
  124.                                 preBuffer,  
  125.                                 preBufferSize,  
  126.                                 0);  
  127.     if (preReceivedLength < 0) {  
  128.         sockClass::error_info("recv() failed.");  
  129.     } else if (preReceivedLength == 0) {  
  130.         std::cout << "Client has been disconnected.\n";  
  131.         return 0;  
  132.     }  
  133.     return preReceivedLength;  
  134. }  
  135.   
  136. int TCPServerSock::TCPSend(const char* send_data,  
  137.                            const int& data_length) const  
  138. {  
  139.     if (data_length > preBufferSize) {  
  140.         throw "Data is too large, resize preBufferSize.";  
  141.     }  
  142.   
  143.     int sent_length = send(    sockFD,  
  144.                             send_data,  
  145.                             data_length,  
  146.                             0);  
  147.     if (sent_length < 0) {  
  148.         sockClass::error_info("send() failed.");  
  149.     } else if (sent_length != data_length) {  
  150.         sockClass::error_info("sent unexpected number of bytes.");  
  151.     }  
  152.   
  153.     return sent_length;  
  154. }  
C++代码
  1. //Filename: SockClass.hpp  
  2.   
  3. #ifndef SOCK_CLASS_HPP  
  4. #define SOCK_CLASS_HPP  
  5.   
  6. #include <iostream>  
  7. #include <winsock2.h>  
  8.   
  9. namespace sockClass  
  10. {  
  11. void error_info(const char* s);  
  12. }  
  13.   
  14. class WinsockAPI{  
  15. private:  
  16.     WSADATA wsaData;  
  17. public:  
  18.     WinsockAPI(int low_byte = 2, int high_byte = 2);  
  19.     ~WinsockAPI();  
  20.     void showVersion() const;  
  21. };  
  22.   
  23. class BaseSock{  
  24. protected:  
  25.     int sockFD;  
  26. public:  
  27.     BaseSock();  
  28.     virtual ~BaseSock() = 0;  
  29.     const int& showSockFD() const;  
  30. };  
  31.   
  32. class TCPListenSock: public BaseSock{  
  33. private:  
  34.     sockaddr_in listenSockAddr;  
  35. public:  
  36.     TCPListenSock(unsigned short listen_port);  
  37.     ~TCPListenSock();  
  38.     void TCPListen(  
  39.         int max_connection_requests = 10) const;  
  40. };  
  41.   
  42. class TCPServerSock: public BaseSock{  
  43. private:  
  44.     sockaddr_in clientSockAddr;  
  45. protected:  
  46.     char* preBuffer;  
  47.     int preBufferSize;  
  48.     mutable int preReceivedLength;  
  49. public:  
  50.     TCPServerSock(  
  51.         const TCPListenSock& listen_sock,  
  52.         int pre_buffer_size = 32);  
  53.     virtual ~TCPServerSock();  
  54.     int TCPReceive() const;  
  55.     int TCPSend(const char* send_data,  
  56.             const int& data_length) const;  
  57. };  
  58.   
  59. #endif //SockClass.hpp  
C++代码
  1. //Filename: AppSock.cpp  
  2.   
  3. #include <string>  
  4. #include "AppSock.hpp"  
  5.   
  6. TCPEchoServer::TCPEchoServer(const TCPListenSock& listen_sock, int pre_buffer_size):  
  7. TCPServerSock(listen_sock, pre_buffer_size)  
  8. {}  
  9.   
  10. TCPEchoServer::~TCPEchoServer()  
  11. {}  
  12.   
  13. bool TCPEchoServer::handEcho() const  
  14. {  
  15.     const std::string SHUTDOWN_CMD = "/shutdown";  
  16.     while (TCPReceive() > 0) {  
  17.         std::string cmd(preBuffer, SHUTDOWN_CMD.size());  
  18.         if (cmd == SHUTDOWN_CMD && preReceivedLength == SHUTDOWN_CMD.size()) {  
  19.             return false;  
  20.         }  
  21.         TCPSend(preBuffer, preReceivedLength);  
  22.     }  
  23.     return true;  
  24. }  
C++代码
  1. //Filename AppSock.hpp  
  2.   
  3. #ifndef APP_SOCK_HPP  
  4. #define APP_SOCK_HPP  
  5.   
  6. #include "SockClass.hpp"  
  7.   
  8. class TCPEchoServer: public TCPServerSock{  
  9. public:  
  10.     TCPEchoServer(  
  11.         const TCPListenSock& listen_sock,  
  12.         int pre_buffer_size = 32);  
  13.     ~TCPEchoServer();  
  14.     bool handEcho() const;  
  15. };  
  16.   
  17. #endif //AppSock.hpp  
C++代码
  1. //Filename: main.cpp  
  2.   
  3. #include "SockClass.hpp"  
  4. #include "AppSock.hpp"  
  5.   
  6. int TCP_echo_server(int argc, char* argv[]);  
  7.   
  8. int main(int argc, char* argv[])  
  9. {  
  10.     int mainRtn = 0;  
  11.     try {  
  12.         mainRtn =TCP_echo_server(argc, argv);  
  13.     }  
  14.     catch (const char* s) {  
  15.         perror(s);  
  16.         return 1;  
  17.     }  
  18.     catch (const int& err) {  
  19.         std::cerr << "Error: " << err << std::endl;  
  20.         return 1;  
  21.     }  
  22.   
  23.     return mainRtn;  
  24. }  
  25.   
  26. int TCP_echo_server(int argc, char* argv[])  
  27. {  
  28.     const unsigned short DEFAULT_PORT = 5000;  
  29.     unsigned short listen_port = DEFAULT_PORT;  
  30.     if (argc == 2 && atoi(argv[1]) > 0) {  
  31.         listen_port = atoi(argv[1]);  
  32.     }  
  33.   
  34.     WinsockAPI winsockInfo;  
  35.     winsockInfo.showVersion();  
  36.   
  37.     TCPListenSock listen_sock(listen_port);  
  38.     listen_sock.TCPListen();  
  39.   
  40.     bool go_on = true;  
  41.     while (go_on){  
  42.         TCPEchoServer echo_server(listen_sock);  
  43.         go_on = echo_server.handEcho();  
  44.     }  
  45.   
  46.     return 0;  
  47. }  

 

除非特别注明,鸡啄米文章均为原创
转载请标明本文地址:http://www.jizhuomi.com/software/420.html
2015年9月2日
作者:鸡啄米 分类:软件开发 浏览: 评论:0