• C++网络编程之客户端程序


    #include<iostream>
    #include<WinSock2.h>
    using namespace std;
    #pragma comment(lib,"Ws2_32.lib")
    const int buf_len=1024;
    const int nDefaultServerPort=10000;
    //把用户在命令行输入的地址转换成整数地址,用户输入的地址可以有两种形式:
    //点分十进制(192.168.1.123)和主机名称形式(localhost)
    u_long ResolveAddress(const char *szServer);
    //连接服务器
    //参数nServerAddr和nPort都必须是网络字节序
    SOCKET ConnectServer(u_long nServerAddr,int nPort);
    //处理回显业务逻辑
    bool ProcessConnection(SOCKET sd);
    bool ShutdownConnection(SOCKET sd);
    void DoWork(const char *szServer,int nPort);//客户端主题函数
    //命令行参数需要包含服务器地址和端口,如果用户没有输入端口,则使用默认的端口nDefaultServerPort
    int main(/*int argc,char *argv[]*/)
    {
    	/*if(argc<2)
    	{
    		return -1;
    	}
    	const char *szServer=argv[1];
    	int nPort=nDefaultServerPort;
    	if(argc>=3)
    	{
    		nPort=atoi(argv[2]);
    	}*/
    	char *szServer="localhost";
    	int nPort=nDefaultServerPort;
    	WSAData wsaData;
    	int nCode;
    	if((nCode=WSAStartup(MAKEWORD(2,2),&wsaData))!=0)
    	{
    		cout<<"WSAStartup error"<<nCode<<endl;
    		return -1;
    	}
    	DoWork(szServer,nPort);
    	WSACleanup();
    	return 0;
    }
    u_long ResolveAddress(const char *szServer)
    {
    	//首先尝试使用inet_addr来转换点分十进制地址,如果返回的是INADDR_NONE,则
    	//表明szServer使用的是主机名称形式,此时需要调用gethostbyname来查询其地址
    	u_long nAddr=inet_addr(szServer);
    	if(nAddr==INADDR_NONE)
    	{
    		hostent *ent=gethostbyname(szServer);
    		if(ent==NULL)
    		{
    			cout<<"gethostbyname error"<<WSAGetLastError()<<endl;
    		}
    		else
    		{
    			nAddr=*((u_long*)ent->h_addr_list[10]);
    		}
    	}
    	if(nAddr==INADDR_NONE)
    	{
    		cout<<"Error resolving address"<<endl;
    	}
    	return nAddr;
    }
    SOCKET ConnectServer(u_long nServerAddr,int nPort)
    {
    	//创建一个套接字
    	SOCKET sd=socket(AF_INET,SOCK_STREAM,0);
    	if(sd==INVALID_SOCKET)
    	{
    		cout<<"socket error"<<WSAGetLastError()<<endl;
    		return INVALID_SOCKET;
    	}
    	//填充服务器套接字地址
    	sockaddr_in saServer;
    	saServer.sin_family=AF_INET;
    	saServer.sin_addr.s_addr=nServerAddr;
    	saServer.sin_port=nPort;
    	//调用connect 来连接到远程服务器
    	if(connect(sd,(sockaddr*)&saServer,sizeof(sockaddr_in))==SOCKET_ERROR)
    	{
    		cout<<"connect error"<<WSAGetLastError()<<endl;
    		closesocket(sd);
    		return INVALID_SOCKET;
    	}
    	return sd;
    }
    bool ProcessConnection(SOCKET sd)
    {
    	char buff[buf_len];
    	//循环直至用户输入Ctrl+Z
    	while(cin>>buff)
    	{
    		int len=(int)strlen(buff);
    		int nSent=0;
    		//把用户的输入发送到服务器
    		while(nSent<len)
    		{
    			int nTemp=send(sd,&buff[nSent],len-nSent,0);
    			if(nTemp>0)
    			{
    				nSent+=nTemp;
    			}
    			else if(nTemp==SOCKET_ERROR)
    			{
    				cout<<"send error"<<WSAGetLastError()<<endl;
    				return false;
    			}
    			else
    			{
    				cout<<"Connection closed unexpectedly by peer"<<endl;
    				return true;
    			}
    		}
    		//接收服务器回显的数据。由于前面客户端发送了len个字节给服务器,因此
    		//这里客户端必须从服务器接收len个字节
    		int nRecv=0;
    		while(nRecv<len)
    		{
    			int nTemp=recv(sd,&buff[nRecv],len-nRecv,0);
    			if(nTemp>0)
    			{
    				nRecv+=nTemp;
    			}
    			else if(nTemp==SOCKET_ERROR)
    			{
    				cout<<"recv error"<<WSAGetLastError()<<endl;
    				return false;
    			}
    			else
    			{
    				cout<<"Connection closed unexpectedly by peer"<<endl;
    				return true;
    			}
    		}
    		//把服务器回显的数据输出到屏幕
    		buff[nRecv]=0;
    		cout<<buff<<endl;
    	}
    	return true;
    }
    void DoWork(const char *szServer,int nPort)
    {
    	//首先调用ResolveAddress来把用户输入的地址转换成整数地址
    	u_long nServerAddr=ResolveAddress(szServer);
    	if(nServerAddr==INADDR_NONE)
    	{
    		return;
    	}
    	//第一阶段,连接服务器
    	SOCKET sd=ConnectServer(nServerAddr,htons(nPort));
    	if(sd==INVALID_SOCKET)
    	{
    		return;
    	}
    	//第二阶段,处理回显业务逻辑
    	if(ProcessConnection(sd)==true)
    	{
    		//第三阶段,关闭连接
    		ShutdownConnection(sd);
    	}
    }
    bool ShutdownConnection(SOCKET sd)
    {
    	//首先发送一个TCP FIN分段,向对方表明已经完成数据发送
    	if(shutdown(sd,SD_SEND)==SOCKET_ERROR)
    	{
    		cout<<"shutdown error"<<WSAGetLastError()<<endl;
    		return false;
    	}
    	char buff[buf_len];
    	int nRecv;
    	//继续接收对方的数据,直到recv返回0为止
    	do{
    		nRecv=recv(sd,buff,buf_len,0);
    		if(nRecv==SOCKET_ERROR)
    		{
    			cout<<"recv error"<<WSAGetLastError()<<endl;
    			return false;
    		}
    		else if(nRecv>0)
    		{
    			cout<<nRecv<<"unexpected bytes received"<<endl;
    		}
    	}while(nRecv!=0);
    	if(closesocket(sd)==SOCKET_ERROR)
    	{
    		cout<<"Closesocket error"<<WSAGetLastError()<<endl;
    		return false;
    	}
    	return true;
    }

  • 相关阅读:
    如何通过cocosStudio将plist大图拆分成原来的小图
    斯坦福大学深度学习视频(CS231n课程)
    杂谈——杭州考驾照历程
    机器学习基础自学笔记2
    深度学习笔记1
    GAN学习指南:从原理入门到制作生成Demo
    GAN实现半监督学习
    无监督深度学习图像分类思路
    无监督学习:从基本概念到四种实现模型
    深度学习-无监督
  • 原文地址:https://www.cnblogs.com/zztong/p/6695274.html
Copyright © 2020-2023  润新知