server.cpp
1 // TestIOCPone.cpp : This file contains the ‘main‘ function. Program execution begins and ends there. 2 // 3 #define _WINSOCK_DEPRECATED_NO_WARNINGS 4 5 #include <iostream> 6 #include <winsock2.h> 7 #include <process.h> 8 #include <MSWSock.h> 9 #include <assert.h> 10 #include <vector> 11 12 #pragma comment(lib ,"ws2_32.lib") 13 14 HANDLE hIocp = 0; 15 LPFN_ACCEPTEX accept_ex_; 16 17 SOCKET sk_listen_; 18 HANDLE h_iocp_; 19 20 21 22 enum CPK_TYPE { 23 CPK_ACCEPT = 1000, //接收请求的完成标识 24 CPK_CLOSE, 25 }; 26 27 28 class io_context : public OVERLAPPED 29 { 30 public: 31 io_context() { 32 memset(static_cast<OVERLAPPED *>(this), 0, sizeof(OVERLAPPED)); 33 client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 34 buf_ = new char[4096]; 35 w_buf_.buf = buf_; 36 w_buf_.len = 4096; 37 } 38 virtual ~io_context() { 39 40 } 41 42 int op_code = 0; 43 WSABUF w_buf_; 44 char* buf_; 45 SOCKET client_socket; 46 }; 47 48 49 50 51 void init_net_func(int s) { 52 GUID guidAcceptEx = WSAID_ACCEPTEX; 53 DWORD bytes = 0; 54 if (WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &guidAcceptEx, 55 sizeof(GUID), &accept_ex_, sizeof(LPFN_ACCEPTEX), &bytes, NULL, 56 NULL) == SOCKET_ERROR) { 57 throw std::exception("get acceptex interface error", GetLastError()); 58 } 59 } 60 61 62 63 void post_accept() 64 { 65 66 67 io_context* pIoContent = new io_context; 68 69 pIoContent->op_code = CPK_ACCEPT; 70 71 DWORD len = 0; 72 73 if (!accept_ex_(sk_listen_, pIoContent->client_socket, pIoContent->buf_, 0, 74 sizeof(sockaddr_in) + 16, sizeof(sockaddr_in) + 16, &len, 75 pIoContent)) { 76 if (WSA_IO_PENDING != WSAGetLastError()) { 77 throw std::exception("acceptex error", GetLastError()); 78 } 79 } 80 } 81 82 83 unsigned int __stdcall work_thread(void* lParam) 84 { 85 LPOVERLAPPED overlapped = NULL; 86 ULONG_PTR cl_key = 0; 87 DWORD recv_bytes = 0; 88 while (true) { 89 BOOL ret = GetQueuedCompletionStatus(h_iocp_, &recv_bytes, &cl_key, 90 &overlapped, 0); 91 92 93 94 if (ret) { 95 std::cout << "recv_bytes=" << recv_bytes << std::endl; 96 io_context* p_io_content = (io_context*)overlapped; 97 98 if (p_io_content->op_code == 2) { 99 std::cout << "send ok" << std::endl; 100 } 101 102 if (p_io_content->op_code == 1) { 103 std::cout << p_io_content->buf_ << std::endl; 104 105 106 107 DWORD send_len = 0; 108 DWORD flags = 0; 109 110 p_io_content->op_code = 2; 111 p_io_content->w_buf_.len = strlen(p_io_content->w_buf_.buf) - 1; 112 113 if (WSASend(p_io_content->client_socket, &p_io_content->w_buf_, 114 1, &send_len, flags, p_io_content, 115 NULL) == SOCKET_ERROR) { 116 if (WSAGetLastError() != WSA_IO_PENDING) { 117 throw std::exception("send error", GetLastError()); 118 } 119 } 120 121 } 122 123 if (CPK_ACCEPT == cl_key) { 124 std::cout << "1" << std::endl; 125 //post_accept(); 126 127 if (!CreateIoCompletionPort((HANDLE)p_io_content->client_socket, h_iocp_, NULL, 128 1)) { 129 throw std::exception("bind listen to iocp", GetLastError()); 130 } 131 132 DWORD recv_len = 0; 133 DWORD flags = 0; 134 p_io_content->op_code = 1; 135 136 if (WSARecv(p_io_content->client_socket, &p_io_content->w_buf_, 137 1, &recv_len, &flags, p_io_content, NULL) == SOCKET_ERROR) { 138 if (WSAGetLastError() != WSA_IO_PENDING) { 139 throw std::exception("recv error", GetLastError()); 140 } 141 } 142 } 143 144 } 145 } 146 147 return 0; 148 } 149 150 int main() 151 { 152 WSADATA wsa; 153 WSAStartup(MAKEWORD(2, 2), &wsa); 154 155 sk_listen_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 156 157 assert(sk_listen_ != INVALID_SOCKET); 158 sockaddr_in addr = { 0 }; 159 addr.sin_family = AF_INET; 160 addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 161 addr.sin_port = htons(12345); 162 163 if (0 != bind(sk_listen_, (struct sockaddr *)&addr, sizeof(sockaddr))) { 164 throw std::exception("bind error", GetLastError()); 165 } 166 int work_thread_num_ = 1; 167 h_iocp_ = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 168 work_thread_num_); 169 if (!h_iocp_) { 170 throw std::exception("create iocp error", GetLastError()); 171 } 172 init_net_func(sk_listen_); 173 listen(sk_listen_, 0); 174 175 176 //handle_work_threads_.resize(work_thread_num_); 177 //for (int i = 0; i < work_thread_num_; i++) 178 { 179 post_accept(); 180 //_beginthreadex(NULL, 0, work_thread, 0, 0, NULL); 181 } 182 183 if (!CreateIoCompletionPort((HANDLE)sk_listen_, h_iocp_, CPK_ACCEPT, work_thread_num_)) { 184 throw std::exception("bind listen to iocp", GetLastError()); 185 } 186 187 work_thread(NULL); 188 189 //while (true) { 190 // Sleep(1000); 191 //} 192 193 WSACleanup(); 194 195 } 196 197
client.cpp
1 #define _WINSOCK_DEPRECATED_NO_WARNINGS 2 3 #include <iostream> 4 #include <winsock2.h> 5 6 #pragma comment(lib ,"ws2_32.lib") 7 8 int main() 9 { 10 WSADATA wsa; 11 WSAStartup(MAKEWORD(2, 2), &wsa); 12 13 sockaddr_in client_addr; 14 client_addr.sin_family = AF_INET; 15 client_addr.sin_port = htons(12345); 16 client_addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); 17 18 SOCKET client_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); 19 20 if (0 == connect(client_socket, (const sockaddr*)&client_addr, sizeof(client_addr))) { 21 const char* pbuf = "client=> server..."; 22 char buf[256] = { 0 }; 23 Sleep(1000); 24 int len = ::send(client_socket, pbuf, strlen(pbuf), 0); 25 if (len > 0) { 26 std::cout << "send len=" << len << std::endl; 27 len = ::recv(client_socket, buf, 256, 0); 28 if (len > 0) { 29 std::cout << buf << std::endl; 30 } 31 } 32 33 } 34 Sleep(1000); 35 closesocket(client_socket); 36 37 38 WSACleanup(); 39 return 0; 40 }
原文:https://www.cnblogs.com/thinkinc999/p/13716711.html