c++下基于windows socket的多线程服务器(基于TCP协议)
之前用c++实现过基于windows socket的单线程TCP服务器(http://www.cnblogs.com/jzincnblogs/p/5170230.html),今天实现了一个多线程的版本,可以接受多个客户端的请求,原理与之前的单线程版本相似,只是在多线程版本中主线程用于监测客户端请求,每当有新客户端请求连接,主线程便新开一个线程用户处理客户端的请求。代码如下: 头文件:1 #if
·
之前用c++实现过基于windows socket的单线程TCP服务器(http://www.cnblogs.com/jzincnblogs/p/5170230.html),今天实现了一个多线程的版本,可以接受多个客户端的请求,原理与之前的单线程版本相似,只是在多线程版本中主线程用于监测客户端请求,每当有新客户端请求连接,主线程便新开一个线程用户处理客户端的请求。代码如下:
头文件:
1 #ifndef SERVER_H
2 #define SERVER_H
3
4 #include <Winsock2.h>
5 #include <windows.h>
6
7 #pragma comment (lib, "ws2_32.lib")
8
9 #define IP_BUF_SIZE 129
10
11 class Server
12 {
13 public:
14 Server();
15 ~Server();
16 Server(const Server &) = delete;
17 Server & operator=(const Server &) = delete;
18 void WaitForClient();
19 private:
20 WORD winsock_ver;
21 WSADATA wsa_data;
22 SOCKET sock_svr;
23 SOCKET sock_clt;
24 HANDLE h_thread;
25 SOCKADDR_IN addr_svr;
26 SOCKADDR_IN addr_clt;
27 int ret_val;
28 int addr_len;
29 char buf_ip[IP_BUF_SIZE];
30 };
31
32 #endif
函数定义:
1 #include "server.h"
2 #include <iostream>
3 #include <WS2tcpip.h>
4
5 using std::cerr;
6 using std::cout;
7 using std::endl;
8
9 #define SERVER_PORT 5000
10 #define MSG_BUF_SIZE 1024
11
12 Server::Server()
13 {
14 cout << "Initializing server...\n";
15 //
16 winsock_ver = MAKEWORD(2, 2);
17 addr_len = sizeof(SOCKADDR_IN);
18 addr_svr.sin_family = AF_INET;
19 addr_svr.sin_port = ::htons(SERVER_PORT);
20 addr_svr.sin_addr.S_un.S_addr = ADDR_ANY;
21 memset(buf_ip, 0, IP_BUF_SIZE);
22 //
23 ret_val = ::WSAStartup(winsock_ver, &wsa_data);
24 if (ret_val != 0)
25 {
26 cerr << "WSA failed to start up!Error code: " << ::WSAGetLastError() << "\n";
27 system("pause");
28 exit(1);
29 }
30 cout << "WSA started up successfully...\n";
31 //
32 sock_svr = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
33 if (sock_svr == INVALID_SOCKET)
34 {
35 cerr << "Failed to create server socket!Error code: " << ::WSAGetLastError() << "\n";
36 ::WSACleanup();
37 system("pause");
38 exit(1);
39 }
40 cout << "Server socket created successfully...\n";
41 //
42 ret_val = ::bind(sock_svr, (SOCKADDR*)&addr_svr, addr_len);
43 if (ret_val != 0)
44 {
45 cerr << "Failed to bind server socket!Error code: " << ::WSAGetLastError() << "\n";
46 ::WSACleanup();
47 system("pause");
48 exit(1);
49 }
50 cout << "Server socket bound successfully...\n";
51 //
52 ret_val = ::listen(sock_svr, SOMAXCONN);
53 if (ret_val == SOCKET_ERROR)
54 {
55 cerr << "Server socket failed to listen!Error code: " << ::WSAGetLastError() << "\n";
56 ::WSACleanup();
57 system("pause");
58 exit(1);
59 }
60 cout << "Server socket started to listen...\n";
61 //
62 cout << "Server started successfully..." << endl;
63 }
64
65 Server::~Server()
66 {
67 ::closesocket(sock_svr);
68 ::closesocket(sock_clt);
69 ::WSACleanup();
70 cout << "Socket closed..." << endl;
71 }
72
73 DWORD WINAPI CreateClientThread(LPVOID lpParameter);
74 //
75 void Server::WaitForClient()
76 {
77 while (true)
78 {
79 sock_clt = ::accept(sock_svr, (SOCKADDR*)&addr_clt, &addr_len);
80 if (sock_clt == INVALID_SOCKET)
81 {
82 cerr << "Failed to accept client!Error code: " << ::WSAGetLastError() << "\n";
83 ::WSACleanup();
84 system("pause");
85 exit(1);
86 }
87 ::InetNtop(addr_clt.sin_family, &addr_clt, buf_ip, IP_BUF_SIZE);
88 cout << "A new client connected...IP address: " << buf_ip << ", port number: " << ::ntohs(addr_clt.sin_port) << endl;
89 h_thread = ::CreateThread(nullptr, 0, CreateClientThread, (LPVOID)sock_clt, 0, nullptr);
90 if (h_thread == NULL)
91 {
92 cerr << "Failed to create a new thread!Error code: " << ::WSAGetLastError() << "\n";
93 ::WSACleanup();
94 system("pause");
95 exit(1);
96 }
97 ::CloseHandle(h_thread);
98 }
99 }
100
101 DWORD WINAPI CreateClientThread(LPVOID lpParameter)
102 {
103 SOCKET sock_clt = (SOCKET)lpParameter;
104 char buf_msg[MSG_BUF_SIZE];
105 int ret_val = 0;
106 int snd_result = 0;
107 do
108 {
109 memset(buf_msg, 0, MSG_BUF_SIZE);
110 ret_val = ::recv(sock_clt, buf_msg, MSG_BUF_SIZE, 0);
111 if (ret_val > 0)
112 {
113 if (strcmp(buf_msg, "exit") == 0)
114 {
115 cout << "Client requests to close the connection..." << endl;
116 break;
117 }
118 cout << "Message received: " << buf_msg << endl;
119 snd_result = ::send(sock_clt, buf_msg, MSG_BUF_SIZE, 0);
120 if (snd_result == SOCKET_ERROR)
121 {
122 cerr << "Failed to send message to client!Error code: " << ::GetLastError() << "\n";
123 ::closesocket(sock_clt);
124 system("pause");
125 return 1;
126 }
127 }
128 else if (ret_val == 0)
129 {
130 cout << "connection closed..." << endl;
131 }
132 else
133 {
134 cerr << "Failed to receive message from client!Error code: " << ::GetLastError() << "\n";
135 ::closesocket(sock_clt);
136 system("pause");
137 return 1;
138 }
139 } while (ret_val > 0);
140 //
141 ret_val = ::shutdown(sock_clt, SD_SEND);
142 if (ret_val == SOCKET_ERROR)
143 {
144 cerr << "Failed to shutdown the client socket!Error code: " << ::GetLastError() << "\n";
145 ::closesocket(sock_clt);
146 system("pause");
147 return 1;
148 }
149 return 0;
150 }
程序入口:
1 #include "server.h"
2
3 int main()
4 {
5 Server svr;
6 svr.WaitForClient();
7 system("pause");
8 return 0;
9 }
点击阅读全文
更多推荐
已为社区贡献7条内容
所有评论(0)