服務端
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;
}