Windows 和 linux 网络互通 发送struct
2015-04-05 21:36
162 查看
贡献一段代码 功能就是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; }
相关文章推荐
- Linux网络设置2——虚拟机中的Linux和Windows网络互通设置 推荐
- Linux网络设置2——虚拟机中的Linux和Windows网络互通设置
- Linux网络设置2――虚拟机中的Linux和Windows网络互通设置
- linux下挂载(mount)光盘镜像文件、移动硬盘、U盘、Windows和NFS网络共享
- 如何在linux系统下挂接(mount)光盘镜像文件、移动硬盘、U盘以及Windows网络共享和UNIX
- windows与wmware下FC linux的网络连接设置
- 从Linux上给Windows发送PopUp消息
- Linux 网络代码导读(接收与发送部分)
- linux下挂载(mount)光盘镜像文件、移动硬盘、U盘、Windows和NFS网络共享
- 经典编程书籍(C++, 网络, Windows, Linux)
- 深入剖析linux网络发送过程
- linux下如何挂接(mount)光盘镜像文件、移动硬盘、U盘、Windows网络共享和NFS网络共享
- 如何在linux系统下挂接(mount)光盘镜像文件、移动硬盘、U盘以及Windows网络共享和UNIX
- linux下挂载(mount)光盘镜像文件、移动硬盘、U盘、Windows和NFS网络共享
- vmware 网络配置实例二 windows xp host + linux
- Windows 到 Linux 之旅: 第 7 部分. 网络
- Linux如何挂接Windows网络共享磁盘
- Linux网络管理之三:从windows访问Linux共享打印 推荐
- vmware下linux通过host-only方式与windows共享网络