服务端
ServerNet.h
#pragma once
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#pragma comment (lib,"ws2_32.lib")
SOCKET sockConn;
HANDLE bufferMutex; // 令其能互斥成功正常通信的信号量句柄
vector clientSocketGroup;
DWORD WINAPI WaitAcceptThread(LPVOID IpParameter);
DWORD WINAPI RecMsgThread(LPVOID IpParameter);
DWORD WINAPI SendMsgThread(LPVOID IpParameter);
mapstring > m_ipSocket;
class CServerNet
{
private:
SOCKET m_sock;
public:
CServerNet(void);
//初始化服务器,返回0表示成功
int Init(const char* address,int port);
//更新数据
void Run();
~CServerNet(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 (mapstring >::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 (mapstring >::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;
}