Windows 和 linux 网络互通 发送struct

贡献一段代码 功能就是linux 系统和 Windows系统网络通信,并且增加了发送struct结构的方法。

Windows Sockect

WindowsSockect.h

#ifndef WINSOCSER
#define WINSOCSER

#pragma once
/********************公用数据预定义***************************/
//WinSock必须的头文件和库
#include <iostream>
#include <list>
using namespace std;
#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
/********************************************************************************************************/
						/*******************客户端*************************/
/********************************************************************************************************/
/*
(1)字段m_iType标识通信协议是TCP还是UDP。
(2)m_Socket保存了本地的套接字,用于发送和接收数据。
(3)m_SockaddrIn记录了连接的服务器的地址和端口信息。
(4)构造函数使用WSAStartup(WINSOCK_VERSION,&wsa)加载WinSock DLL。
(5)init函数初始化客户端进行通信的服务器协议类型,IP和端口。
(6)getProto,getIP,getPort分别提取服务器信息。
(7)sendData向服务器发送指定缓冲区的数据。
(8)getData从服务器接收数据保存到指定缓冲区。
(9)析构函数使用closesocket(m_Socket)关闭套接字,WSACleanup卸载WinSock DLL。
*/
class Client
{
	int m_iType;//通信协议类型
	SOCKET m_Socket;//本地套接字
	sockaddr_in m_SockaddrIn;//服务器地址结构
public:
	Client();
	void 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);//接收数据
	virtual ~Client(void);
};
/********************************************************************************************************/
				/*********************服务器********************/
/********************************************************************************************************/
//服务器类Server比客户端复杂一些,首先服务器需要处理多个客户端连接请求,因此需要为每个客户端开辟新的线程(UDP不需要)
/*
(1)和Client类似,Server也需要字段m_Socket,m_SockaddrIn和m_iType,这里引入clientAddrs保存客户端的信息列表,用addClient和delClient维护这个列表。
(2)CRITICAL_SECTION *cs记录服务器的临界区对象,用于保持线程处理函数内的同步。
(3)构造函数和析构函数与Client功能类似,getProto,getIP,getPort允许获取服务器和客户端的地址信息。
(4)init初始化服务器参数,start启动服务器。
(5)connect,procRequest,disConnect用于实现用户自定义的服务器行为。
(6)友元函数threadProc是线程处理函数。
*/
class Server
{
	CRITICAL_SECTION *cs;//临界区对象
	int m_iType;//记录数据包类型
	SOCKET m_Socket;//本地socket
	sockaddr_in m_SockaddrIn;//服务器地址
	list<sockaddr_in*> clientAddrs;//客户端地址结构列表
	sockaddr_in* addClient(sockaddr_in client);//添加客户端地址结构
	void delClient(sockaddr_in *client);//删除客户端地址结构
	friend DWORD WINAPI threadProc(LPVOID lpParam);//线程处理函数作为友元函数
public:
	Server();
	void init(int inet_type,char*addr,unsigned short port);
	void start();//启动服务器  这个专门针对那些多客户端的应用程序
	char* getProto();//获取协议类型
	char* getIP(sockaddr_in*m_SockaddrIn=NULL);//获取IP
	unsigned short getPort(sockaddr_in*m_SockaddrIn=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 ~Server(void);
};
/*
void testServer()
{
	int type;
	cout<<"选择通信类型(TCP=0/UDP=1):";
	cin>>type;
	Server s;
	if(type==1)
		s.init(UDP_DATA,"127.0.0.1",90);
	else
		s.init(TCP_DATA,"127.0.0.1",80);
	cout<<s.getProto()<<"服务器"<<s.getIP()<<"["<<s.getPort()<<"]"<<"启动成功。"<<endl;
	s.start();
}
void testClient()
{
	int type;
	cout<<"选择通信类型(TCP=0/UDP=1):";
	cin>>type;
	Client c;
	if(type==1)
		c.init(UDP_DATA,"127.0.0.1",90);
	else
		c.init(TCP_DATA,"192.168.1.116",4567);
	cout<<"客户端发起对"<<c.getIP()<<"["<<c.getPort()<<"]的"<<c.getProto()<<"连接。"<<endl;
	char buff[MAX_BUFFER_LEN];
	while(true)
	{
		//cout<<"发送"<<c.getProto()<<"数据到"<<c.getIP()<<"["<<c.getPort()<<"]:";
		//cin>>buff;
		//if(strcmp(buff,"q")==0)
		//break;
		//c.sendData(buff,MAX_BUFFER_LEN);
		c.getData(buff,4);
		cout<<"接收"<<c.getProto()<<"数据从"<<c.getIP()<<"["<<c.getPort()<<"]:"<<buff<<endl;
	}
}

#include "WindowsSockect.h"
#include <iostream>
using namespace std;
int main()
{
int flag;
cout<<"构建服务器/客户端(0-服务器|1-客户端):";
cin>>flag;
if(flag==0)
testServer();
else
testClient();
return 0;
}*/
#endif

WindowsSockect.cpp

#include "WindowsSockect.h"
/********************************************************************************************************/
										//	Client 
/********************************************************************************************************/
Client::Client()
{
	WSADATA wsa;
	int rslt=WSAStartup(WINSOCK_VERSION,&wsa);//加载WinSock DLL
	assert(rslt==0);
}
Client::~Client(void)
{
	if(m_Socket!=INVALID_SOCKET)
		closesocket(m_Socket);
	WSACleanup();//卸载WinSock DLL
}
/*
首先,Client根据不同的协议类型创建不同的套接字m_Socket,然后填充m_SockaddrIn结构,
其中inet_addr是将字符串IP地址转化为网络字节序的IP地址,htons将整形转化为网络字
节顺序,对于短整型,相当于高低字节交换。如果通信是TCP协议,那么还需要客户端主动
发起connect连接,UDP不需要做。
*/
void Client::init(int inet_type,char*addr,unsigned short port)
{
	int rslt;
	m_iType=inet_type;
	if(m_iType==TCP_DATA)//TCP数据
		m_Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//创建TCP套接字
	else if(m_iType==UDP_DATA)//UDP数据
		m_Socket=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);//创建UDP套接字
	assert(m_Socket!=INVALID_SOCKET);
	m_SockaddrIn.sin_family=AF_INET;
	m_SockaddrIn.sin_addr.S_un.S_addr=inet_addr(addr);
	m_SockaddrIn.sin_port=htons(port);
	memset(m_SockaddrIn.sin_zero,0,8);
	if(m_iType==TCP_DATA)//TCP数据
	{
		rslt=connect(m_Socket,(sockaddr*)&m_SockaddrIn,sizeof(sockaddr));//客户端连接请求
		assert(rslt==0);
	}
}

void Client::sendData(const char * buff,const int len)//发送数据
{
	int rslt;
	int addrLen=sizeof(sockaddr_in);
	if(m_iType==TCP_DATA)//TCP数据
	{
		rslt=send(m_Socket,buff,len,0);
	}
	else if(m_iType==UDP_DATA)//UDP数据
	{
		rslt=sendto(m_Socket,buff,len,0,(sockaddr*)&m_SockaddrIn,addrLen);
	}
	assert(rslt>0);
}
void Client::getData(char * buff,const int len)
{
	int rslt;
	int addrLen=sizeof(sockaddr_in);
	memset(buff,0,len);
	if(m_iType==TCP_DATA)//TCP数据
	{
		int iGetOk = 0;
		while(iGetOk < len)
		{
			rslt=recv(m_Socket,buff + iGetOk,len - iGetOk,0);
			if(rslt == -1)
			{
				perror("Tcp Get Data");
				exit(1);
			}
			iGetOk += rslt;
		}		
		buff[len]='\0';
	}
	else if(m_iType==UDP_DATA)//UDP数据
	{
		int iGetOk = 0;
		while(iGetOk < len)
		{

			rslt=recvfrom(m_Socket,buff + iGetOk,len-iGetOk,0,(sockaddr*)&m_SockaddrIn,&addrLen);
			if(rslt == -1)
			{
				perror("Tcp Get Data");
				exit(1);
			}
			iGetOk += rslt;
		}		
		buff[len]='\0';
	}
	assert(rslt>0);
}
//有时需要获取客户端连接的服务器信息
//需要额外说明的是,inet_ntoa将网络字节序的IP地址转换为字符串IP,和前边inet_addr功能相反,ntohs和htons功能相反。
char* Client::getProto()
{
	if(m_iType==TCP_DATA)
		return "TCP";
	else if(m_iType==UDP_DATA)
		return "UDP";
	else
		return "";
}

char* Client::getIP()
{
	return inet_ntoa(m_SockaddrIn.sin_addr);
}

unsigned short Client::getPort()
{
	return ntohs(m_SockaddrIn.sin_port);
}
/*****************************************Server********************************************************/
									// Server
/*****************************************************************************************************/
//首先根据通信协议类型创建本地套接字m_Socket,填充地址m_SockaddrIn,使用bind函数绑定服务器参数,对于TCP通信,需要listen进行服务器监听。
void Server::init(int inet_type,char*addr,unsigned short port)
{
	int rslt;
	m_iType=inet_type;
	if(m_iType==TCP_DATA)//TCP数据
		m_Socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);//创建TCP套接字
	else if(m_iType==UDP_DATA)//UDP数据
		m_Socket=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);//创建UDP套接字
	assert(m_Socket!=INVALID_SOCKET);
	m_SockaddrIn.sin_family=AF_INET;
	m_SockaddrIn.sin_addr.S_un.S_addr=inet_addr(addr);
	m_SockaddrIn.sin_port=htons(port);
	memset(m_SockaddrIn.sin_zero,0,8);
	rslt=bind(m_Socket,(sockaddr*)&m_SockaddrIn,sizeof(m_SockaddrIn));//绑定地址和端口
	assert(rslt==0);
	if(m_iType==TCP_DATA)//TCP需要侦听
	{
		rslt=listen(m_Socket,MAX_TCP_CONNECT);//监听客户端连接
		assert(rslt==0);
	}
}
struct SockParam
{
	SOCKET rsock;//远程的socket
	sockaddr_in *raddr;//远程地址结构
	Server*pServer;//服务器对象指针
	SockParam(SOCKET rs,sockaddr_in*ra,Server*ps)
	{
		rsock=rs;
		raddr=ra;
		pServer=ps;
	}
};
/*
线程处理函数使用传递的服务器对象指针pServer获取服务器socket,
地址和临界区对象。和客户端不同的是,服务接收发送数据使用的socket
不是本地socket而是客户端的socket!为了保证线程的并发控制,
使用EnterCriticalSection和LeaveCriticalSection保证,中间的请求处
理函数和UDP使用的相同。另外,线程的退出表示客户端的连接断开,
这里更新客户端列表并调用disConnect允许服务器做最后的处理。
和connect类似,这一对函数调用只针对TCP通信,对于UDP通信不存在调用关系。
*/
DWORD WINAPI threadProc(LPVOID lpParam)//TCP线程处理函数
{
	SockParam sp=*(SockParam*)lpParam;
	Server*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数据
	}while(rslt!=0||rslt!=SOCKET_ERROR);
	s->delClient(clientAddr);
	s->disConnect(clientAddr);//断开连接后处理
	return 0;
}
//初始化服务器后使用start启动服务器:
// TCP服务器不断的监听新的连接请求,
// 使用accept接收请求,获得客户端的地址结构和socket,
// 然后更新客户端列表,调用connect进行连接时候的处理,
// 使用CreateThread创建一个TCP客户端线程,线程参数传递了
// 客户端socket和地址,以及服务器对象的指针,
// 交给procThread处理数据的接收和发送。
void Server::start()
{
	int rslt;
	sockaddr_in client;//客户端地址结构
	int addrLen=sizeof(client);
	SOCKET clientSock;//客户端socket
	char buff[MAX_BUFFER_LEN];//UDP数据缓存
	while(true)
	{
		if(m_iType==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_iType==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数据
		}
	}
}
void Server::connect(sockaddr_in*client)
{
    cout<<"客户端"<<getIP(client)<<"["<<getPort(client)<<"]"<<"连接。"<<endl;
}
int Server::procRequest(sockaddr_in*client,const char* req,int reqLen,char*resp)
{
    cout<<getIP(client)<<"["<<getPort(client)<<"]:"<<req<<endl;
    if(m_iType==TCP_DATA)
        strcpy_s(resp,8,"TCP Back");
    else if(m_iType==UDP_DATA)      
        strcpy_s(resp,8,"UDP Back");
    return 10;
}
void Server::disConnect(sockaddr_in*client)
{
    cout<<"客户端"<<getIP(client)<<"["<<getPort(client)<<"]"<<"断开。"<<endl;
}
Server::Server()
{
	cs=new CRITICAL_SECTION();
	InitializeCriticalSection(cs);//初始化临界区
	WSADATA wsa;
	int rslt=WSAStartup(WINSOCK_VERSION,&wsa);//加载WinSock DLL
	assert(rslt==0);
}
char* Server::getProto()
{
	if(m_iType==TCP_DATA)
		return "TCP";
	else if(m_iType==UDP_DATA)
		return "UDP";
	else
		return "";
}
char* Server::getIP(sockaddr_in*addr)
{
	if(addr==NULL)
		addr=&m_SockaddrIn;
	return inet_ntoa(addr->sin_addr);
}
unsigned short Server::getPort(sockaddr_in*addr)
{
	if(addr==NULL)
		addr=&m_SockaddrIn;
	return htons(addr->sin_port);
}
sockaddr_in* Server::addClient(sockaddr_in client)
{
	sockaddr_in*pc=new sockaddr_in(client);
	clientAddrs.push_back(pc);
	return pc;
}
void Server::delClient(sockaddr_in *client)
{
	assert(client!=NULL);
	delete client;
	clientAddrs.remove(client);
}
Server::~Server(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;
}


WindowsSockectMain.cpp

#include "WindowsSockect.h"
#include <iostream>
using namespace std;
typedef struct _stDoubleInt
{
	int m_iFirst;
	int m_iSecond;
	
}stDoubleInt;
int main()
{
	Client c;
	c.init(TCP_DATA,"192.168.1.116",4567);
	cout<<"客户端发起对"<<c.getIP()<<"["<<c.getPort()<<"]的"<<c.getProto()<<"连接。"<<endl;
	stDoubleInt *myNode=(stDoubleInt*)malloc(sizeof(stDoubleInt));
	int needRecv=sizeof(stDoubleInt);
	char *buffer=(char*)malloc(needRecv);
	stDoubleInt stDoubleIntBuf[100];
	int iCal = 0,iCalTem = 0;
	while(iCal < 55)
	{
		c.getData((char *)buffer,needRecv);
		memcpy(myNode,buffer,needRecv);
		std::cout<<myNode->m_iFirst<<"   "<<myNode->m_iSecond<<std::endl;	
		stDoubleIntBuf[iCalTem].m_iFirst = myNode->m_iFirst;
		stDoubleIntBuf[iCalTem].m_iSecond =myNode->m_iSecond;
		iCal++;
		iCalTem = iCal;
	}
	getchar();
	return 0;
}

Linux  Sockect


Tcp.h

#ifndef QTCP_H
#define QTCP_H

#include <netdb.h>
/**********Tcp client*****************/
class MyTcpClient
{
    public:
             MyTcpClient();
            ~MyTcpClient();
    public:
             void ClientCloseSockfd();
             int  GetClientFd()const;
             void ClientControl(const char *cpHostName,const unsigned short int &iPort);
             int  ClientSend(unsigned const char *buffer	,const int &iSize);
             int  ClientReceive(char *pBuffer,const int &iBufferSize,const int &iWantByte);
    private:
             void ClientGetHostByName(const char *cpHostName);
             void ClientSocket();
             void ClientSocketAddresInit(const unsigned short int &iPort);
             void ClientConnect();
    private:
            unsigned  int                 m_iMaxQueConnNum;       //表示最大连接数
            int 								m_iSockfd;
            int 								m_iSendbytes;
            int 								m_iRecvbytes;
    private:
               typedef  struct
               {
                    struct hostent 	    *	  host;
                    struct sockaddr_in 		  serv_addr;
               }MyClientStruct;
              MyClientStruct  *           m_stpMyClientControl;
};
/*****************tcp server****************/
class  MyTcpServer
{
    public:
           MyTcpServer();
           ~MyTcpServer();
    private:
           void ServerSocket();
           void ServerSocketAddresInit(const unsigned short int &iPort);
           void ServerSetSocketOpt();
           void ServerBindListen();
           void ServerAccept();
           void ServerDisplay();
           void ServerCloseSockfd();
    public:
           void ServerControl(const unsigned short int &iPort);
    public:
           int  ServerReceive(char *pBuffer,const int &iBufferSize,const int &iWantByte);
           int  ServerSend(const char *buffer, const int &iSize);
    private:
           typedef  struct
           {
            struct sockaddr_in                  server_sockaddr;
            struct sockaddr_in			        client_sockaddr;
           }MyServerStruct;
           MyServerStruct  *                  m_stpMyServerControl;
    private:
    //unsigned short int               PORT;                     //端口号
    unsigned  int                    m_iMaxQueConnNum;           //表示最大连接数
    int                              m_iSinSize;
    int 								 m_iRecvbytes;
    int 							     m_iSendbytes;
    int                               m_iSockfd;
    //int                               m_iClientFd;
};
#endif // QTCP_H

tcp.cpp


#include"Tcp.h"
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
/*****************tcp client*************************/
MyTcpClient::MyTcpClient()
{
    //this->PORT=4322;                     //另一端的server port 端口号
    this->m_iMaxQueConnNum=5;         //表示最大连接数
    this->m_iSockfd=0;
    this->m_iSendbytes=0;
    this->m_iRecvbytes=0;
    this->m_stpMyClientControl =new MyClientStruct;
    ::memset(m_stpMyClientControl,0,sizeof(MyClientStruct));
    std::cout<<"Create MyTcpClient Class finished !"<<std::endl;

}
MyTcpClient::~MyTcpClient()
{
    if(!m_stpMyClientControl)
    {
      delete m_stpMyClientControl;
      m_stpMyClientControl=NULL;
      std::cout<<"Delete m_stpMyClientControl !!!"<<std::endl;

    }

    }
void MyTcpClient::ClientGetHostByName(const char *cpHostName)
{

    /*地址解析函数*/
    if ((m_stpMyClientControl->host = gethostbyname(cpHostName)) == NULL)
    {
        perror("gethostbyname");
        exit(1);
    }
    std::cout<<"The Client Host Name:"<<cpHostName<<std::endl;
}
void MyTcpClient::ClientSocket()
{
    /*创建socket*/
    if ((m_iSockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
    {
        perror("socket");
        exit(1);
    }
    std::cout<<"The Client Create The Socket !!"<<std::endl;

}
void MyTcpClient::ClientSocketAddresInit(const unsigned short int &iPort)
{

    /*设置sockaddr_in 结构体中相关参数*/
    m_stpMyClientControl->serv_addr.sin_family = AF_INET;
    m_stpMyClientControl->serv_addr.sin_port = htons(iPort);
    m_stpMyClientControl->serv_addr.sin_addr = *((struct in_addr *)m_stpMyClientControl->host->h_addr);
    bzero(&(m_stpMyClientControl->serv_addr.sin_zero), 8);
    std::cout<<"The client_sockaddr_init OK! The PORT:"<<iPort<<std::endl;
    }
void MyTcpClient::ClientConnect()
{
       /*调用connect函数主动发起对服务器端的连接*/
       int  my_true=1;
       while(my_true)
       {
            if(connect(m_iSockfd,(struct sockaddr *)&m_stpMyClientControl->serv_addr, sizeof(struct sockaddr))== -1)
            {
                std::cout<<"Can not connect,I  will try"<<std::endl;
            }
            else
                my_true=0;
       }
       std::cout<<"The Client Connect OK !!"<<std::endl;
}
int MyTcpClient::ClientSend(unsigned const char *buffer,const int &iSize)//这里必须要用size,因为传过来的buffer只是一个地址。
{
    int m_iSendbytes_ok=0;
    while(m_iSendbytes_ok<iSize)
    {
        if ((m_iSendbytes = send(m_iSockfd, buffer+m_iSendbytes_ok,iSize-m_iSendbytes_ok, 0)) == -1)
        {
            perror("send");
            exit(1);
        }
        m_iSendbytes_ok+=m_iSendbytes;
    }
    std::cout<<"Send OK!!"<<std::endl;
    return  m_iSendbytes;
}
int MyTcpClient::ClientReceive(char*pBuffer,const int &iBufferSize,const int &iWantByte)
{
    memset(pBuffer , 0, iBufferSize);
    int iGet = recv(m_iSockfd,pBuffer,iWantByte,0);
    if(iGet < iWantByte)
    {
        std::cout<<"Socket Get Not Equle to WantByte"<<std::endl;
    }
    if(iGet < iBufferSize)
    {
        pBuffer[iGet] = '\0';
    }
    return iGet;
}
void MyTcpClient::ClientCloseSockfd(){
    close(m_iSockfd);
}
void MyTcpClient::ClientControl(const char *cpHostName,const unsigned short int &iPort){

	    ClientGetHostByName(cpHostName);
	    ClientSocket();
       ClientSocketAddresInit(iPort);
       // 接收缓冲区
       int nRecvBufLen = 32 * 1024; //设置为32K
       setsockopt(m_iSockfd,SOL_SOCKET, SO_RCVBUF, (const char*)&nRecvBufLen, sizeof(int));
       ClientConnect();
    }
int MyTcpClient::GetClientFd()const
{
    return m_iSockfd;
}
/*****************************tcp_server***************************************/
MyTcpServer::MyTcpServer()
{
    //this->PORT=4321;       //这个是服务端专属端口号
    this->m_iMaxQueConnNum=5;
    this->m_iSinSize=0;
    this->m_iRecvbytes=0;
    this->m_iSendbytes=0;
    this->m_iSockfd=0;
    this->m_iSockfd=0;
    this->m_stpMyServerControl =new MyServerStruct;
    ::memset(m_stpMyServerControl,0,sizeof(MyServerStruct));
    std::cout<<"Create MyTcpServer Class finished !"<<std::endl;
}
MyTcpServer::~MyTcpServer()
{
    if(m_stpMyServerControl)
         delete m_stpMyServerControl;
    m_stpMyServerControl=NULL;
    std::cout<<"Delete MyTcpServer Class finished !"<<std::endl;
}
void  MyTcpServer::ServerSocket()
{
        /*建立socket连接*/
        if ((m_iSockfd = socket(AF_INET,SOCK_STREAM,0))== -1)   //最后一个参数表示为 自动选择选取的 通信类型  TCP / UDP
        {
            perror("socket");
            exit(1);
        }
        std::cout<<"Server Socket Id ="<<m_iSockfd<<std::endl;
    }
void MyTcpServer::ServerSocketAddresInit(const unsigned short int &iPort)
{
        /*设置sockaddr_in 结构体中相关参数*/
       m_stpMyServerControl->server_sockaddr.sin_family = AF_INET;
       m_stpMyServerControl->server_sockaddr.sin_port = htons(iPort);
       m_stpMyServerControl->server_sockaddr.sin_addr.s_addr = INADDR_ANY;
       bzero(&(m_stpMyServerControl->server_sockaddr.sin_zero), 8);
    }
void MyTcpServer::ServerSetSocketOpt()
{
    bool Reused=true;/*使得重复使用本地地址与套接字进行绑定 设置调用closesocket()后,仍可继续重用该socket*/
    setsockopt(m_iSockfd, SOL_SOCKET, SO_REUSEADDR,( const char* )&Reused,sizeof(bool));

    int nSendBufLen = 32*1024;  //设置为32K   //发送缓冲区
    setsockopt( m_iSockfd, SOL_SOCKET, SO_SNDBUF, ( const char* )&nSendBufLen, sizeof(int));

    int nZero = 0;
    setsockopt(m_iSockfd, SOL_SOCKET, SO_SNDBUF, ( char * )&nZero, sizeof( nZero ) );
}

void MyTcpServer::ServerBindListen()
{
    /*绑定函数bind*/
    if (bind(m_iSockfd, (struct sockaddr *)&m_stpMyServerControl->server_sockaddr, sizeof(struct sockaddr))== -1)
    {
        perror("bind");
        exit(1);
    }
    std::cout<<"Server Bind success!"<<std::endl;
    /*调用listen函数*/
    if (listen(m_iSockfd, m_iMaxQueConnNum) == -1)
    {
        perror("listen");
        exit(1);
    }
    std::cout<<"server listening ............."<<std::endl;
    //std::cout<<"Server is  Listening.... In IP:"<<inet_ntoa(m_stpMyServerControl->server_sockaddr.sin_addr)<<std::endl;
}
void MyTcpServer::ServerAccept()
{
    /*调用accept函数,等待客户端的连接*/
    if ((m_iSockfd = accept(m_iSockfd, (struct sockaddr *)&m_stpMyServerControl->client_sockaddr,
                                     (socklen_t*)&m_iSinSize)) == -1)
    {
        perror("accept");
        exit(1);
    }
    std::cout<<"server accept"<<std::endl;
   //std::cout<<"server: got connection from"<<inet_ntoa(m_stpMyServerControl->client_sockaddr.sin_addr)<<std::endl;
}
int MyTcpServer::ServerReceive(char*pBuffer,const int &iBufferSize,const int &iWantByte)
{
    memset(pBuffer , 0, iBufferSize);
    int iGet = recv(m_iSockfd,pBuffer,iWantByte,0);
    if(iGet < iWantByte)
    {
      std::cout<<"Socket Get Not Equle to WantByte"<<std::endl;
    }
    if(iGet < iBufferSize)
    {
        pBuffer[iGet] = '\0';
    }
    return iGet;
}
int MyTcpServer::ServerSend(const char *buffer,const int &iSize)//这里必须要用size,因为传过来的buffer只是一个地址。
{
    int sendbytes_ok=0;
    while(sendbytes_ok<iSize)
    {
        if ((m_iSendbytes = send(m_iSockfd, buffer+sendbytes_ok,iSize-sendbytes_ok, 0)) == -1)
        {
            perror("send");
            exit(1);
        }
        sendbytes_ok+=m_iSendbytes;
    }
    std::cout<<"Send OK!!"<<std::endl;
    return  m_iSendbytes;
}
void MyTcpServer::ServerCloseSockfd()
{
    close(m_iSockfd);
    std::cout<<"Server Close The Sockfd !!!"<<std::endl;
}
void MyTcpServer::ServerControl(const unsigned short int &iPort)
{
        ServerSocket();
        ServerSocketAddresInit(iPort);
        ServerSetSocketOpt();
        ServerBindListen();
        ServerAccept();
}

main.cpp

//============================================================================
// Name        : WindowsSockectTest.cpp
// Author      : sfe
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include"Tcp.h"
#include<stdlib.h>
#include<string.h>
using namespace std;
typedef struct _stDoubleInt
{
	int m_iFirst;
	int m_iSecond;
}stDoubleInt;
int main() {
	cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
	system("ifconfig");
   	MyTcpServer oMyTcpServer;
   	oMyTcpServer.ServerControl(4567);
//   	string pMjpegBuffer("Fuck");
   	stDoubleInt st1={1,2};
   	char *buffer = (char * )malloc(sizeof(stDoubleInt));
   	memcpy(buffer,&st1,sizeof(stDoubleInt));
   	std::cout<<buffer<<"    "<<sizeof(stDoubleInt)<<std::endl;
   	int n = 50;
   	while(1)//( n > 0)
   	{
   	 //  oMyTcpServer.ServerSend(pMjpegBuffer.c_str(),pMjpegBuffer.size());
   	      oMyTcpServer.ServerSend(buffer,sizeof(stDoubleInt));
   	   //n--;
   	}
	return 0;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值