服務端
ServerNet.h
#pragma once #include#include #include #include #include #include #include
ServerNet.cpp
#include "ServerNet.h" int CServerNet::Init( const char* address,int port ) { int rlt = 0; //用於記錄錯誤信息,並輸出 int iErrorMsg; //初始化WinSock WSAData wsaData; iErrorMsg = WSAStartup(MAKEWORD(1,1),&wsaData); if (iErrorMsg != NO_ERROR) { //初始化WinSock失敗 printf("wsastartup failed with error : %d\n",iErrorMsg); //WSAGetLastError() rlt = 1; return rlt; } //創建服務端Socket m_sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if (m_sock == INVALID_SOCKET) { //創建Socket異常 printf("socket failed with error : %d\n",WSAGetLastError()); rlt = 2; return rlt; } //聲明信息 sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = port; serverAddr.sin_addr.s_addr = inet_addr(address); //綁定 iErrorMsg = bind(m_sock,(sockaddr*)&serverAddr,sizeof(serverAddr)); if (iErrorMsg < 0) { //綁定失敗 printf("bind failed with error : %d\n",iErrorMsg); rlt = 3; return rlt; } return rlt; } void CServerNet::Run() { //公開連接 listen(m_sock,20); int len = sizeof(sockaddr); bufferMutex = CreateSemaphore(NULL, 1, 1, NULL); //HANDLE sendThread = CreateThread(NULL,0,) HANDLE acceptThread = CreateThread(NULL, 0, WaitAcceptThread, (LPVOID)m_sock, 0, NULL); //do //{ // //接收信息 // newSocket = accept(m_sock,(sockaddr*)&tcpAddr,&len); // // if (newSocket == INVALID_SOCKET) // { // //非可用socket // } // else // { // //新socket連接 // printf("new socket connect : %d\n",newSocket); // //消息處理 // do // { // printf("process\n"); // //接收數據 // memset(buf,0,sizeof(buf)); // rval = recv(newSocket,buf,1024,0); // // if (rval == SOCKET_ERROR) // { // //這應該是個異常,當客戶端沒有調用closeSocket就直接退出游戲的時候,將會進入這裡 // printf("recv socket error\n"); // break; // } // // // if (rval == 0) // //recv返回0表示正常退出 // printf("ending connection"); // else // //顯示接收到的數據 // printf("recv %s\n",buf); // }while(rval != 0); // //關閉對應Accept的socket // closesocket(newSocket); // } // // //} while (1); //關閉自身的Socket WaitForSingleObject(acceptThread, INFINITE); // 等待線程結束 //WaitForSingleObject(sendThread, INFINITE); // 等待線程結束 //CloseHandle(sendThread); CloseHandle(bufferMutex); WSACleanup(); // 終止對套接字庫的使用 closesocket(m_sock); } CServerNet::CServerNet(void) { } CServerNet::~CServerNet(void) { } DWORD WINAPI WaitAcceptThread(LPVOID IpParameter) { SOCKET m_socket = (SOCKET)IpParameter; while(true) { sockaddr_in tcpAddr; int len = sizeof(sockaddr_in); sockConn = accept(m_socket, (sockaddr*)&tcpAddr, &len); char t[20]; printf("%s:%d上線",inet_ntoa(tcpAddr.sin_addr),tcpAddr.sin_port); sprintf(t,"%s:%d",inet_ntoa(tcpAddr.sin_addr),tcpAddr.sin_port); string t1=t; if (SOCKET_ERROR != sockConn) { clientSocketGroup.push_back(sockConn); m_ipSocket[sockConn] = t1; } HANDLE receiveThread = CreateThread(NULL, 0, RecMsgThread, (LPVOID)sockConn, 0, NULL); WaitForSingleObject(bufferMutex, INFINITE); // P(資源未被占用) if(NULL == receiveThread) { printf("\nCreatThread AnswerThread() failed.\n"); } else{ printf("\nCreate Receive Client Thread OK.\n"); } ReleaseSemaphore(bufferMutex, 1, NULL); } } DWORD WINAPI RecMsgThread(LPVOID IpParameter) { SOCKET ClientSocket=(SOCKET)(LPVOID)IpParameter; int rval; while(1) { char recvBuf[1024]; rval = recv(ClientSocket, recvBuf, 1024, 0); WaitForSingleObject(bufferMutex, INFINITE); if (rval == SOCKET_ERROR) { printf("ONE Client Exit\n"); vector::iterator result = find(clientSocketGroup.begin(), clientSocketGroup.end(), ClientSocket); clientSocketGroup.erase(result); for (map ::iterator i=m_ipSocket.begin(); i!=m_ipSocket.end(); i++) { if (i->first == ClientSocket) { printf("%s下線\n",m_ipSocket[ClientSocket].c_str()); m_ipSocket.erase(i); break; } } closesocket(ClientSocket); ReleaseSemaphore(bufferMutex, 1, NULL); break; } printf("%s Says: %s\n", m_ipSocket[ClientSocket].c_str(), recvBuf); // 接收信息 ReleaseSemaphore(bufferMutex, 1, NULL); } return 0; } int main() { CServerNet serverNet; int iRlt = serverNet.Init("127.0.0.1",8888); if (iRlt == 0) { printf("init ok...\n"); serverNet.Run(); } else printf("serverNet init failed with error : %d\n",iRlt); system("pause"); return 0; }
客戶端
ClientNet.h
#pragma once #include#include #pragma comment(lib, "Ws2_32.lib") class CClientNet { private: SOCKET m_sock; public: CClientNet(void); //連接上指定服務器 int Connect(int port,const char* address); //發送信息 int SendMsg(const char* msg,int len); //關閉 void Close(); ~CClientNet(void); };
ServerNet.cpp
#include "ServerNet.h" int CServerNet::Init( const char* address,int port ) { int rlt = 0; //用於記錄錯誤信息,並輸出 int iErrorMsg; //初始化WinSock WSAData wsaData; iErrorMsg = WSAStartup(MAKEWORD(1,1),&wsaData); if (iErrorMsg != NO_ERROR) { //初始化WinSock失敗 printf("wsastartup failed with error : %d\n",iErrorMsg); //WSAGetLastError() rlt = 1; return rlt; } //創建服務端Socket m_sock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if (m_sock == INVALID_SOCKET) { //創建Socket異常 printf("socket failed with error : %d\n",WSAGetLastError()); rlt = 2; return rlt; } //聲明信息 sockaddr_in serverAddr; serverAddr.sin_family = AF_INET; serverAddr.sin_port = port; serverAddr.sin_addr.s_addr = inet_addr(address); //綁定 iErrorMsg = bind(m_sock,(sockaddr*)&serverAddr,sizeof(serverAddr)); if (iErrorMsg < 0) { //綁定失敗 printf("bind failed with error : %d\n",iErrorMsg); rlt = 3; return rlt; } return rlt; } void CServerNet::Run() { //公開連接 listen(m_sock,20); int len = sizeof(sockaddr); bufferMutex = CreateSemaphore(NULL, 1, 1, NULL); //HANDLE sendThread = CreateThread(NULL,0,) HANDLE acceptThread = CreateThread(NULL, 0, WaitAcceptThread, (LPVOID)m_sock, 0, NULL); //do //{ // //接收信息 // newSocket = accept(m_sock,(sockaddr*)&tcpAddr,&len); // // if (newSocket == INVALID_SOCKET) // { // //非可用socket // } // else // { // //新socket連接 // printf("new socket connect : %d\n",newSocket); // //消息處理 // do // { // printf("process\n"); // //接收數據 // memset(buf,0,sizeof(buf)); // rval = recv(newSocket,buf,1024,0); // // if (rval == SOCKET_ERROR) // { // //這應該是個異常,當客戶端沒有調用closeSocket就直接退出游戲的時候,將會進入這裡 // printf("recv socket error\n"); // break; // } // // // if (rval == 0) // //recv返回0表示正常退出 // printf("ending connection"); // else // //顯示接收到的數據 // printf("recv %s\n",buf); // }while(rval != 0); // //關閉對應Accept的socket // closesocket(newSocket); // } // // //} while (1); //關閉自身的Socket WaitForSingleObject(acceptThread, INFINITE); // 等待線程結束 //WaitForSingleObject(sendThread, INFINITE); // 等待線程結束 //CloseHandle(sendThread); CloseHandle(bufferMutex); WSACleanup(); // 終止對套接字庫的使用 closesocket(m_sock); } CServerNet::CServerNet(void) { } CServerNet::~CServerNet(void) { } DWORD WINAPI WaitAcceptThread(LPVOID IpParameter) { SOCKET m_socket = (SOCKET)IpParameter; while(true) { sockaddr_in tcpAddr; int len = sizeof(sockaddr_in); sockConn = accept(m_socket, (sockaddr*)&tcpAddr, &len); char t[20]; printf("%s:%d上線",inet_ntoa(tcpAddr.sin_addr),tcpAddr.sin_port); sprintf(t,"%s:%d",inet_ntoa(tcpAddr.sin_addr),tcpAddr.sin_port); string t1=t; if (SOCKET_ERROR != sockConn) { clientSocketGroup.push_back(sockConn); m_ipSocket[sockConn] = t1; } HANDLE receiveThread = CreateThread(NULL, 0, RecMsgThread, (LPVOID)sockConn, 0, NULL); WaitForSingleObject(bufferMutex, INFINITE); // P(資源未被占用) if(NULL == receiveThread) { printf("\nCreatThread AnswerThread() failed.\n"); } else{ printf("\nCreate Receive Client Thread OK.\n"); } ReleaseSemaphore(bufferMutex, 1, NULL); } } DWORD WINAPI RecMsgThread(LPVOID IpParameter) { SOCKET ClientSocket=(SOCKET)(LPVOID)IpParameter; int rval; while(1) { char recvBuf[1024]; rval = recv(ClientSocket, recvBuf, 1024, 0); WaitForSingleObject(bufferMutex, INFINITE); if (rval == SOCKET_ERROR) { printf("ONE Client Exit\n"); vector::iterator result = find(clientSocketGroup.begin(), clientSocketGroup.end(), ClientSocket); clientSocketGroup.erase(result); for (map ::iterator i=m_ipSocket.begin(); i!=m_ipSocket.end(); i++) { if (i->first == ClientSocket) { printf("%s下線\n",m_ipSocket[ClientSocket].c_str()); m_ipSocket.erase(i); break; } } closesocket(ClientSocket); ReleaseSemaphore(bufferMutex, 1, NULL); break; } printf("%s Says: %s\n", m_ipSocket[ClientSocket].c_str(), recvBuf); // 接收信息 ReleaseSemaphore(bufferMutex, 1, NULL); } return 0; } int main() { CServerNet serverNet; int iRlt = serverNet.Init("127.0.0.1",8888); if (iRlt == 0) { printf("init ok...\n"); serverNet.Run(); } else printf("serverNet init failed with error : %d\n",iRlt); system("pause"); return 0; }