WINDOWS下客户端,服务器端代码,可以直接copy使用

//****************************客户端*****************************************************************

#include "SocketClient.h"

#pragma once

//WinSock必须的头文件和库
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")

//辅助头文件
#include <assert.h>

//网络数据类型
#define TCP_DATA 1
#define UDP_DATA 2

//TCP连接限制
#define MAX_TCP_CONNECT 10

//缓冲区上限
#define MAX_BUFFER_LEN 1024

class CSocketClient
{
 //******************************
 int m_type;//通信协议类型
 SOCKET m_socket;//本地套接字
 sockaddr_in serverAddr;//服务器地址结构

 //******************************
public:
 int init(int inet_type,char*addr,unsigned short port);//初始化通信协议,地址,端口
 char *getProto();//获取通信协议类型
 char *getIP();//获取IP地址
 unsigned short getPort();//获取端口
 void sendData(const char * buff,const int len);//发送数据
 void getData(char * buff,const int len);//接收数据

 CSocketClient(void);
 ~CSocketClient(void);
 void close(void);
};

//**********************************客户端CPP文件***************************************************

#include "StdAfx.h"
#include "SocketClient.h"

CSocketClient::CSocketClient(void)
{
 WSADATA wsa;
 int rslt=WSAStartup(WINSOCK_VERSION,&wsa);//加载WinSock DLL
 assert(rslt==0);
}

int CSocketClient::init(int inet_type,char*addr,unsigned short port)
{
 int rslt;
 m_type=inet_type;
 if(m_type==TCP_DATA)//TCP数据
  m_socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//创建TCP套接字
 else if(m_type==UDP_DATA)//UDP数据
  m_socket=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);//创建UDP套接字
// assert(m_socket!=INVALID_SOCKET);
 serverAddr.sin_family=AF_INET;
 serverAddr.sin_addr.S_un.S_addr=inet_addr(addr);
 serverAddr.sin_port=htons(port);
 memset(serverAddr.sin_zero,0,8);

 if(m_type==TCP_DATA)//TCP数据
 {
  rslt=connect(m_socket,(sockaddr*)&serverAddr,sizeof(sockaddr));//客户端连接请求
//  assert(rslt==0);
 }
 return rslt;
}

void CSocketClient::sendData(const char * buff,const int len)
{
 int rslt;
 int addrLen=sizeof(sockaddr_in);
// memset(buff,0,len);

 if(m_type==TCP_DATA)//TCP数据
 {
  rslt=send(m_socket,buff,len,0);
 }
 else if(m_type==UDP_DATA)//UDP数据
 {
  rslt=sendto(m_socket,buff,len,0,(sockaddr*)&serverAddr,addrLen);
 }
 //assert(rslt>0);

}

void CSocketClient::getData(char * buff,const int len)
{
 int rslt;
 int addrLen=sizeof(sockaddr_in);
 memset(buff,0,len);

 if(m_type==TCP_DATA)//TCP数据
 {
  rslt=recv(m_socket,buff,len,0);
 }
 else if(m_type==UDP_DATA)//UDP数据
 {
  rslt=recvfrom(m_socket,buff,len,0,(sockaddr*)&serverAddr,&addrLen);
 }
 //assert(rslt>0);
}

char *CSocketClient::getProto()
{
 if(m_type==TCP_DATA)
  return "TCP";
 else if(m_type==UDP_DATA)
  return "UDP";
 else
  return "";
}

char *CSocketClient::getIP()
{
 return inet_ntoa(serverAddr.sin_addr);
}

unsigned short CSocketClient::getPort()
{
 return ntohs(serverAddr.sin_port);
}

CSocketClient::~CSocketClient(void)
{
 if(m_socket!=INVALID_SOCKET)
  closesocket(m_socket);
 WSACleanup();//卸载WinSock DLL
}

void CSocketClient::close(void)
{
 if(m_socket!=INVALID_SOCKET)
  closesocket(m_socket);
}

 

 

//======================================================================================

//***************************************************服务器端****************************************************************************

#include "Cserver.h"

#pragma once
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")
//辅助头文件
#include <assert.h>

//网络数据类型
#define TCP_DATA 1
#define UDP_DATA 2

//TCP连接限制
#define MAX_TCP_CONNECT 10

//缓冲区上限
#define MAX_BUFFER_LEN 1024


#include <list>
using namespace std;

class Cserver
{
 CRITICAL_SECTION *cs;//临界区对象

 int m_type;//记录数据包类型
 SOCKET m_socket;//本地socket
 sockaddr_in serverAddr;//服务器地址
 list<sockaddr_in*> clientAddrs;//客户端地址结构列表
 sockaddr_in* addClient(sockaddr_in client);//添加客户端地址结构
 void delClient(sockaddr_in *client);//删除客户端地址结构
 friend DWORD WINAPI threadProc(LPVOID lpParam);//线程处理函数作为友元函数
public:
 Cserver();
 void init(int inet_type,char*addr,unsigned short port);
 void start();//启动服务器
 char* getProto();//获取协议类型
 char* getIP(sockaddr_in*serverAddr=NULL);//获取IP
 unsigned short getPort(sockaddr_in*serverAddr=NULL);//获取端口
 virtual void connect(sockaddr_in*client);//连接时候处理
 virtual int procRequest(sockaddr_in*client,const char* req,int reqLen,char*resp);//处理客户端请求
 virtual void disConnect(sockaddr_in*client);//断开时候处理
 virtual ~Cserver(void);
};


//***************************************************服务器端CPP文件****************************************************************************

 

#include "StdAfx.h"
#include "Cserver.h"
#include <iostream>
struct SockParam
{
 SOCKET rsock;//远程的socket
 sockaddr_in *raddr;//远程地址结构
 Cserver*pServer;//服务器对象指针
 SockParam(SOCKET rs,sockaddr_in*ra,Cserver*ps)
 {
  rsock=rs;
  raddr=ra;
  pServer=ps;
 }
};
 static int i=0;
Cserver::Cserver(void)
{
 cs=new CRITICAL_SECTION();
 InitializeCriticalSection(cs);//初始化临界区
 WSADATA wsa;
 int rslt=WSAStartup(WINSOCK_VERSION,&wsa);//加载WinSock DLL
 assert(rslt==0);

}

void Cserver::init(int inet_type,char*addr,unsigned short port)
{
 int rslt;
 m_type=inet_type;
 if(m_type==TCP_DATA)//TCP数据
  m_socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//创建TCP套接字
 else if(m_type==UDP_DATA)//UDP数据
  m_socket=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);//创建UDP套接字
 assert(m_socket!=INVALID_SOCKET);
 serverAddr.sin_family=AF_INET;
 serverAddr.sin_addr.S_un.S_addr=inet_addr(addr);
 serverAddr.sin_port=htons(port);
 memset(serverAddr.sin_zero,0,8);
 rslt=bind(m_socket,(sockaddr*)&serverAddr,sizeof(serverAddr));//绑定地址和端口
 assert(rslt==0);
 if(m_type==TCP_DATA)//TCP需要侦听
 {
  rslt=listen(m_socket,MAX_TCP_CONNECT);//监听客户端连接
  assert(rslt==0);
 }
}

void Cserver::start()
{
 int rslt;
 sockaddr_in client;//客户端地址结构
 int addrLen=sizeof(client);
 SOCKET clientSock;//客户端socket
 char buff[MAX_BUFFER_LEN];//UDP数据缓存
 while(true)
 {
  if(m_type==TCP_DATA)//TCP数据
  {
   clientSock=accept(m_socket,(sockaddr*)&client,&addrLen);//接收请求
   if(clientSock==INVALID_SOCKET)
    break;
   assert(clientSock!=INVALID_SOCKET);
   sockaddr_in*pc=addClient(client);//添加一个客户端
   connect(pc);//连接处理函数
   SockParam sp(clientSock,pc,this);//参数结构
   HANDLE thread=CreateThread(NULL,0,threadProc,(LPVOID)&sp,0,NULL);//创建连接线程
   assert(thread!=NULL);
   CloseHandle(thread);//关闭线程
  }
  else if(m_type==UDP_DATA)//UDP数据
  {
   memset(buff,0,MAX_BUFFER_LEN);
   rslt=recvfrom(m_socket,buff,MAX_BUFFER_LEN,0,(sockaddr*)&client,&addrLen);
   assert(rslt>0);
   char resp[MAX_BUFFER_LEN]={0};//接收处理后的数据
   rslt=procRequest(&client,buff,rslt,resp);//处理请求
   rslt=sendto(m_socket,resp,rslt,0,(sockaddr*)&client,addrLen);//发送udp数据
  }
 }
}

char* Cserver::getProto()
{
 if(m_type==TCP_DATA)
  return "TCP";
 else if(m_type==UDP_DATA)
  return "UDP";
 else
  return "";
}

char* Cserver::getIP(sockaddr_in*addr)
{
 if(addr==NULL)
  addr=&serverAddr;
 return inet_ntoa(addr->sin_addr);
}

unsigned short Cserver::getPort(sockaddr_in*addr)
{
 if(addr==NULL)
  addr=&serverAddr;
 return htons(addr->sin_port);
}

sockaddr_in* Cserver::addClient(sockaddr_in client)
{
 sockaddr_in*pc=new sockaddr_in(client);
 clientAddrs.push_back(pc);
 return pc;
}

void Cserver::delClient(sockaddr_in *client)
{
 assert(client!=NULL);
 delete client;
 clientAddrs.remove(client);
}


void Cserver::connect(sockaddr_in*client)
{
 cout<<"客户端"<<getIP(client)<<"["<<getPort(client)<<"]"<<"连接。"<<endl;
}

int Cserver::procRequest(sockaddr_in*client,const char* req,int reqLen,char*resp)
{
 cout<<getIP(client)<<"["<<getPort(client)<<"]:"<<req<<endl;
 if(m_type==TCP_DATA)
 {
  if (i==1)
  {
   strcpy(resp,"TCP第二次回复");
  }
  else
  {
   i++;
   strcpy(resp,"TCP第一次回复");
  }
  
 }
 else if(m_type==UDP_DATA)
  strcpy(resp,"UDP回复");
 return 15;
}

void Cserver::disConnect(sockaddr_in*client)
{
 cout<<"客户端"<<getIP(client)<<"["<<getPort(client)<<"]"<<"断开。"<<endl;
}

 

Cserver::~Cserver(void)
{
 for(list<sockaddr_in*>::iterator i=clientAddrs.begin();i!=clientAddrs.end();++i)//清空客户端地址结构
 {
  delete *i;
 }
 clientAddrs.clear();
 if(m_socket!=INVALID_SOCKET)
  closesocket(m_socket);//关闭服务器socket
 WSACleanup();//卸载WinSock DLL
 DeleteCriticalSection(cs);
 delete cs;

}

DWORD WINAPI threadProc(LPVOID lpParam)//TCP线程处理函数
{
 SockParam sp=*(SockParam*)lpParam;
 Cserver*s=sp.pServer;
 SOCKET sock=s->m_socket;
 SOCKET clientSock=sp.rsock;
 sockaddr_in *clientAddr=sp.raddr;

 CRITICAL_SECTION*cs=s->cs;
 int rslt;
 char req[MAX_BUFFER_LEN+1]={0};//数据缓冲区,多留一个字节,方便输出
 do
 {
  rslt=recv(clientSock,req,MAX_BUFFER_LEN,0);//接收数据
  if(rslt<=0)
   break;
  char resp[MAX_BUFFER_LEN]={0};//接收处理后的数据
  EnterCriticalSection(cs);
  rslt=s->procRequest(clientAddr,req,rslt,resp);//处理后返回数据的长度
  LeaveCriticalSection(cs);
  assert(rslt<=MAX_BUFFER_LEN);//不会超过MAX_BUFFER_LEN
  //rslt=send(clientSock,resp,rslt,0);//发送tcp数据
  rslt=send(clientSock,resp,rslt,0);//发送tcp数据
 }
 while(rslt!=0||rslt!=SOCKET_ERROR);
 s->delClient(clientAddr);
 s->disConnect(clientAddr);//断开连接后处理
 return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值