zoukankan      html  css  js  c++  java
  • C++Socket编程—TCP通信

    一.TCP协议

    传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

    TCP通过校验和、序列号、确认应答、重发控制、连接管理以及窗口控制等机制实现可靠性传输。

    udp -无连接(可不确认进行直接发送)
    tcp -面向连接(必须经过双方确认)



    2.TCP协议创建过程

    1)创建socket
    2)绑定端口
    3)监听(转给另外一个socket)
    4)接受连接
    5)收发数据

    3.代码实例—TCP通信,服务器可以接受客户端发来的信息

    服务器:

            //1.创建TCP socket
    	SOCKET sockServer = socket(AF_INET,
    		SOCK_STREAM,
    		IPPROTO_TCP
    	);
    	//2.绑定端口
    	sockaddr_in siServer;
    	siServer.sin_family = AF_INET;
    	siServer.sin_port = htons(8888);
    	siServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    	int nRet = bind(sockServer, (sockaddr*)&siServer, sizeof(siServer));
    	if (nRet == SOCKET_ERROR)
    	{
    		printf("端口绑定失败
    ");
    		return 0;
    	}
    	//3.监听
    	nRet = listen(sockServer, SOMAXCONN);//监听最大值
    	if (nRet == SOCKET_ERROR)
    	{
    		printf("监听失败
    ");
    		return 0;
    	}
    	//4.接受连接
    	while (true)
    		{
    			// 	4) 接受连接
    			sockaddr_in siClient;
    			int nSize = sizeof(siClient);
    			SOCKET sockClient = accept(sockServer, (sockaddr*)&siClient, &nSize);
    			if (sockClient == SOCKET_ERROR)
    			{
    				printf("接受连接失败 
    ");
    				return 0;
    			}
    			printf("IP:%s port:%d 连接到服务器. 
    ",
    				inet_ntoa(siClient.sin_addr),
    				ntohs(siClient.sin_port));
    	
    			HANDLE hTread = CreateThread(NULL, 0, HandleClientThread, (LPVOID)sockClient, 0, NULL);//用来收发数据的线程
    			CloseHandle(hTread);
    		}
    		
    		
    //5.创建一个线程用来收发数据
    DWORD WINAPI HandleClientThread(LPVOID pParam)
    {
    	SOCKET sockClient = (SOCKET)pParam;
    
    	while (TRUE)
    	{
    		//5) 收发数据
    		char aryBuff[MAXWORD] = { 0 };
    		int nRet = recv(sockClient, aryBuff, sizeof(aryBuff), 0);
    		if (nRet == 0 || nRet == SOCKET_ERROR)
    		{
    			printf("接受数据失败 
    ");
    			return 0;
    		}
    		printf("收到数据: %s 
    ", aryBuff);
    
    		char szBuff[] = { "recv OK 
    " };
    		nRet = send(sockClient, szBuff, sizeof(szBuff), 0);
    		if (nRet == SOCKET_ERROR)
    		{
    			printf("数据发送失败 
    ");
    			return 0;
    		}
    	}
    
    	return 0;
    }
    

     客户端:

    	//1.创建TCP socket
    	SOCKET sockClient = socket(AF_INET,
    		SOCK_STREAM,
    		IPPROTO_TCP
    	);
    
    	//2.连接服务器
    	sockaddr_in siServer;
    	siServer.sin_family = AF_INET;
    	siServer.sin_port = htons(8888);
    	siServer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    	int nRet = connect(sockClient, (sockaddr*)&siServer, sizeof(siServer));
    	if (nRet == SOCKET_ERROR)
    	{
    		printf("服务器连接失败");
    	}
    	//3.收发数据
    	while (TRUE)
    	{
    		
    		char szBuff[MAXWORD] = { 0 };
    		cin >> szBuff;
    
    		nRet = send(sockClient, szBuff, sizeof(szBuff), 0);
    		if (nRet == SOCKET_ERROR)
    		{
    			printf("数据发送失败 
    ");
    			return 0;
    		}
    
    		char aryBuff[MAXWORD] = { 0 };
    		nRet = recv(sockClient, aryBuff, sizeof(aryBuff), 0);
    		if (nRet == 0 || nRet == SOCKET_ERROR)
    		{
    			printf("接受数据失败 
    ");
    			return 0;
    		}
    		printf("收到数据: %s 
    ", aryBuff);
    	}
    
    
    	closesocket(sockClient);
    	return 0;
    
  • 相关阅读:
    UART中的硬件流控RTS与CTS
    Yii smsto短信接口的函数
    分布式选主 利用Mysql ACID和Lease协议实现选主和高可用
    Extjs GridPanel 合计功能 解决滚动条滚动问题和页面刷新滚动条回到初始位置问题。
    基于ARM+LINUX的无线视频采集系统设计搭建嵌入式web服务器
    C++里父类的析构函数为什么声明为virtual
    重量过载 = 重载
    Spread Studio中文支持图解
    Android用户如何FQ访问被封锁的媒体资源
    将myeclipse 10.x以下版本web project的导入到myeclipse blue 2013 部署没有项目名
  • 原文地址:https://www.cnblogs.com/zhaoyixiang/p/12798148.html
Copyright © 2011-2022 走看看