网络编程的练习2
网络编程的练习2 这是一个服务器端的类,采用的是TCP传输
服务端 客户机
socket()
bind()
listen() socket()
accept()
阻塞.等待客户 connect()
read() write()
处理服务请求
write() read()
close() close()
/*
*******************************************************
2004 12 06
stephen
*******************************************************
*/
#include <Winsock2.h>
#pragma comment(lib,"Ws2_32.lib")
#define MAXSIZE 50
#define WM_RECEIVEDATA WM_USER+1002
class CNetServer
{
public:
CNetServer();
CNetServer(int port);
~CNetServer();
//读数据
static DWORD WINAPI ThreadServer(LPVOID n);
//初始化服务器
bool InitNetServer();
// 发送到指定的客户端
bool SendDataToClient(int nclient,char* data,int len);
// 发送到所有的客户端
bool SendDataToClient(char* data,int len);
//指定接收数据的窗口句柄
inline void SethWnd(HWND hWnd)
{
m_hWnd = hWnd;
}
int getCount();
// 返回错误信息
char* GetLastError();
//关闭服务器
void CloseServer();
//关闭服务器
void DestoryServer();
private:
HANDLE hThread;
HWND m_hWnd;
int port;
char szError[256];
char getData[256];
int nReceive;
int addlen;
SOCKET sock;
SOCKET clientSocket[MAXSIZE];
sockaddr_in servaddr;
WSADATA wsData;
};
CNetServer::CNetServer()
{
this->sock = INVALID_SOCKET;
this->hThread=NULL;
this->port = 9999;
for(int i=0;i<MAXSIZE;i++)
{
clientSocket[i] = INVALID_SOCKET;
}
}
CNetServer::CNetServer(int port)
{
this->sock = INVALID_SOCKET;
this->hThread=NULL;
this->port = port;
for(int i=0;i<MAXSIZE;i++)
{
clientSocket[i] = INVALID_SOCKET;
}
}
CNetServer::~CNetServer()
{
this->DestoryServer();
}
char* CNetServer::GetLastError()
{
return this->szError;
}
bool CNetServer::InitNetServer()
{
if(WSAStartup(MAKEWORD(1,1),&this->wsData) != 0)
{
wsprintf(this->szError,TEXT("WSAStartup failed.Error:%d"),WSAGetLastError());
return false;
}
this->servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
this->servaddr.sin_family = AF_INET;
this->servaddr.sin_port = htons(this->port);
this->addlen = sizeof(servaddr);
sock = socket(AF_INET,SOCK_STREAM,0);
if( sock == SOCKET_ERROR)
{
wsprintf(this->szError,TEXT("bind failed.Error:%d"),WSAGetLastError());
return false;
}
if(bind(sock,(sockaddr*)&servaddr,sizeof(servaddr)) == SOCKET_ERROR)
{
wsprintf(this->szError,TEXT("bind failed.Error:%d"),WSAGetLastError());
return false;
}
else
{
listen(sock,5);
hThread = CreateThread(NULL,0,CNetServer::ThreadServer,this,0,NULL);
return true;
}
}
int CNetServer::getCount()
{
for( int i =0;i<MAXSIZE;i++)
{
if(clientSocket[i] == INVALID_SOCKET)
return i;
}
return -1;
}
DWORD WINAPI CNetServer::ThreadServer(LPVOID n)
{
CNetServer* pServer = (CNetServer*)n;
char buff[1024] = "";
int rev = 1,flag = 0;
int clientcount=-1;
clientcount = pServer->getCount();
if(clientcount == -1)
{
return 0L;
}
else
{
rev = 1;
pServer->clientSocket[clientcount] =
accept(pServer->sock,(sockaddr*)&(pServer->servaddr),
&pServer->addlen);
if( pServer->clientSocket[clientcount] == INVALID_SOCKET)
{
wsprintf(pServer->szError,TEXT("accept failed.Error:%d"),WSAGetLastError());
return 0L;
}
else
{
::CreateThread(NULL,0,CNetServer::ThreadServer,pServer,0,NULL);
while(rev != SOCKET_ERROR)
{
rev = recv(pServer->clientSocket[clientcount],
buff,1024,0);
if(rev != SOCKET_ERROR)
{
//::SendMessage(pServer->m_hWnd,WM_RECEIVEDATA,0,(LPARAM)buff);
MessageBox(NULL,(LPCTSTR)buff,"receiveData",0);
}
}
}
}
return 1;
}
bool CNetServer::SendDataToClient(int nclient,char* data,int len)
{
int i=0;
if(sock == INVALID_SOCKET)
return false;
if(clientSocket[nclient] == INVALID_SOCKET)
return false;
if(send(clientSocket[nclient],data,len,0) == SOCKET_ERROR)
{
wsprintf(this->szError,TEXT("send failed.Error:%d"),WSAGetLastError ());
return false;
}
return true;
}
bool CNetServer::SendDataToClient(char* data,int len)
{
for(int i=0;i<MAXSIZE;i++)
{
if(clientSocket[i] != INVALID_SOCKET)
if(send(clientSocket[i],data,len,0) == SOCKET_ERROR)
{
wsprintf(this->szError,TEXT("send failed.Error:%d"),WSAGetLastError ());
return false;
}
}
}
void CNetServer::CloseServer()
{
WaitForSingleObject(this->hThread,INFINITE);
for(int i=0;i<MAXSIZE;i++)
{
if(clientSocket[i] !=INVALID_SOCKET)
closesocket(clientSocket[i]);
}
WSACleanup();
}
void CNetServer::DestoryServer()
{
DWORD exitCode=0;
GetExitCodeThread(this->hThread,&exitCode);
TerminateThread(this->hThread,exitCode);
for(int i=0;i<MAXSIZE;i++)
{
if(clientSocket[i] !=INVALID_SOCKET)
closesocket(clientSocket[i]);
WSACleanup();
}
}
/*
********************************************************************************
TEST
********************************************************************************
*/
#include "stdafx.h"
#include <iostream.h>
#include <string>
#include "NetServer.h"
int main()
{
CNetServer net(9999);
if(net.InitNetServer()==false)
cout<<"InitNetServer"<<net.GetLastError()<<endl;
char data[1024]="";
while(cin>>data !="exit")
{
net.SendDataToClient(data,sizeof(data));
net.SendDataToClient(1,data,sizeof(data));
}
net.CloseServer();
}
/*
可用telnet 127.0.0.1 9999 测试,也可用CNet测试, 不当之处,欢迎指点
*/