网络编程的练习2

类别:VC语言 点击:0 评论:0 推荐:

 这是一个服务器端的类,采用的是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测试, 不当之处,欢迎指点
*/

本文地址:http://com.8s8s.com/it/it399.htm