<span style="font-size:18px;"></pre><pre name="code" class="cpp"><pre name="code" class="cpp">main函数和工作线程文件 </span>
<span style="font-size:18px;">#include "stdafx.h" #include <WinSock2.h> #include "CDSocket.h" #pragma comment(lib, "ws2_32.lib") struct PER_HANDLE_DATA { SOCKET s; sockaddr_in addr; PER_HANDLE_DATA (SOCKET s0, sockaddr_in addr0) : s(s0), addr(addr0){} }; struct PER_IO_DATA { WSAOVERLAPPED ol; char buf[BUFFER_SIZE]; int nOperation; PER_IO_DATA (int op) { ZeroMemory(this, sizeof(PER_IO_DATA)); nOperation = op; } }; DWORD WINAPI ServerThread(LPVOID lpParam); SockInit si; int _tmain(int argc, _TCHAR* argv[]) { //创建完成端口 HANDLE hIocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0); //创建工作线程 HANDLE hThread = CreateThread(NULL, 0, ServerThread, (LPVOID)hIocp, 0, 0); //创建socket CDSocket sListen; sListen.Create(); //绑定 sListen.Bind(4567); //监听 sListen.Listen(); while (true) { //接受连接 sockaddr_in remoteAddr; CDSocket sRemote = sListen.Accept((sockaddr*)&remoteAddr); printf("接受ip=%s port=%d的连接\n", inet_ntoa(remoteAddr.sin_addr), ntohs(remoteAddr.sin_port)); //连接socket关联完成端口 PER_HANDLE_DATA* pPerHandle = new PER_HANDLE_DATA(sRemote, remoteAddr); CreateIoCompletionPort((HANDLE)pPerHandle->s, hIocp, (ULONG_PTR)pPerHandle, 0); //投递异步接收请求 /* PER_IO_DATA* pPerIO = (PER_IO_DATA *)::GlobalAlloc(GPTR, sizeof(PER_IO_DATA)); pPerIO->nOperation = OP_READ; OVERLAPPED结构必须为0 否则一定失败 tmd老子调了一下午 */ PER_IO_DATA* pPerIO = new PER_IO_DATA(OP_READ); sRemote.Recv(pPerIO->buf, BUFFER_SIZE, NULL, (LPWSAOVERLAPPED)pPerIO); } return 0; } DWORD WINAPI ServerThread(LPVOID lpParam) { HANDLE hIocp = (HANDLE)lpParam; DWORD dwTrans; PER_HANDLE_DATA* pPerHandle = NULL; PER_IO_DATA* pPerIO = NULL; while (true) { BOOL bOK = GetQueuedCompletionStatus(hIocp, &dwTrans, (PULONG_PTR)&pPerHandle, (LPOVERLAPPED*)&pPerIO, WSA_INFINITE); if (!bOK) { closesocket(pPerHandle->s); delete pPerHandle; delete pPerIO; continue; } if (dwTrans == 0 && (pPerIO->nOperation == OP_READ || pPerIO->nOperation == OP_WRITE)) { closesocket(pPerHandle->s); delete pPerHandle; delete pPerIO; continue; } switch (pPerIO->nOperation) { case OP_READ: { pPerIO->buf[dwTrans] = '\0'; printf(pPerIO->buf); /*WSABUF buf; buf.buf = pPerIO->buf; buf.len = BUFFER_SIZE; pPerIO->nOperation = OP_READ; DWORD nFlags = 0; WSARecv(pPerHandle->s, &buf, 1, &dwTrans, &nFlags, lpOverLapped, NULL);*/ CDSocket sClient(pPerHandle->s); //sClient.Recv(pPerIO->buf, BUFFER_SIZE, NULL, (LPWSAOVERLAPPED)pPerIO); sClient.Send(pPerIO->buf, strlen(pPerIO->buf)); } case OP_WRITE: { } case OP_ACCEPT: { } default: break; } } return 0; } </span>
<span style="font-size:18px;">//SockInit是初始化socket环境的类,定义一个此类的全局变量即可</span>
<span style="font-size:18px;">//socket的简单封装CDSocket.h #include <WinSock2.h> #define BUFFER_SIZE 1024 #define OP_READ 1 #define OP_WRITE 2 #define OP_ACCEPT 3 struct SockInit { SockInit() { WSADATA wsaData; WSAStartup(MAKEWORD(2, 2), &wsaData); } ~SockInit() { WSACleanup(); } }; class CDSocket { public: CDSocket(SOCKET hSocket = NULL) :m_hSocket(hSocket) {} ~CDSocket() { if (m_hSocket != NULL) { closesocket(m_hSocket); } } CDSocket& operator=(const CDSocket& rhs) { if (m_hSocket != NULL) { closesocket(m_hSocket); } m_hSocket = rhs.m_hSocket; return *this; } CDSocket& operator=(const SOCKET& hSocket) { if (m_hSocket != NULL) { closesocket(m_hSocket); } m_hSocket = hSocket; return *this; } bool Create() { m_hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == m_hSocket) { m_hSocket = NULL; return false; } return true; } int Bind(short nPort) { sockaddr_in localAddr; localAddr.sin_family = AF_INET; localAddr.sin_port = ntohs(nPort); localAddr.sin_addr.S_un.S_addr = INADDR_ANY; return bind(m_hSocket, (sockaddr*)&localAddr, sizeof(localAddr)); } int Listen(int backend = 10) { return listen(m_hSocket, backend); } CDSocket Accept(sockaddr* remoteAddr) { int nRemoteAddrLen = sizeof(sockaddr); return CDSocket(accept(m_hSocket, remoteAddr, &nRemoteAddrLen)); } int Connect(const char* szIp, short nPort) { sockaddr_in remoteAddr; remoteAddr.sin_family = AF_INET; remoteAddr.sin_port = ntohs(nPort); remoteAddr.sin_addr.S_un.S_addr = inet_addr(szIp); return connect(m_hSocket, (sockaddr*)&remoteAddr, sizeof(remoteAddr)); } int Send(char* szBuf, int len) { return send(m_hSocket, szBuf, len, 0); } int Recv(char* szBuf, int nBufSize, LPDWORD lpNumberOfBytesRecvd, LPWSAOVERLAPPED lpOverLapped) { WSABUF buf; buf.buf = szBuf; buf.len = nBufSize; DWORD dwFlags = 0; return WSARecv(m_hSocket, &buf, 1, lpNumberOfBytesRecvd, &dwFlags, lpOverLapped, NULL); } operator SOCKET() { return m_hSocket; } void Attach(SOCKET hSocket) { if (m_hSocket != NULL) { closesocket(m_hSocket); } m_hSocket = hSocket; } private: SOCKET m_hSocket; };</span>