当前位置:   article > 正文

Linux用c++实现TCP通信(详细注解)_c++ tcp通讯

c++ tcp通讯

用c++实现TCP通信(详细注解)

主要为socket通信的知识
Server端:

#include <iostream>
using namespace std;
#include <winsock2.h>
#pragma comment(lib,"Ws2_32.lib")

const int BUF_SIZE = 2048;			//缓冲区大小
char sendbuf[BUF_SIZE];		//发送缓冲区
char recvbuf[BUF_SIZE];		//接受缓冲区

void initialization()			//初始化操作
{
	//WSADATA是一种数据结构,用来存储被WSAStartup函数调用后返回的Windows sockets数据,包含Winsock.dll执行的数据。需要头文件
	WSADATA wsadata;

	//MAKEWORD声明调用不同的Winsock版本。例如MAKEWORD(2,2)就是调用2.2版
	WORD wsaversion = MAKEWORD(2, 2);	


	//WSAStartup函数必须是应用程序或DLL调用的第一个Windows套接字函数
	//可以进行初始化操作,检测winsock版本与调用dll是否一致,成功返回0
	if (WSAStartup(wsaversion, &wsadata) != 0)
	{
		cout << "载入socket库失败" << endl;
	}
	else {
		cout << "初始化成功" << endl;
	}

}

int main()
{
	SOCKET sockSer;	//创建服务器套接字
	SOCKET sockCli;	

	//SOCKADDR_IN是系统封装的一个结构体,具体包含了成员变量:sin_family、sin_addr、sin_zero
	SOCKADDR_IN addrSer;
	SOCKADDR_IN addrCli;


	initialization();


	//socket(int domain, int type, int protocol)
	//domain表示要使用的协议AF_INET指ipv4,type指套接字类型 stream指tcp
	//协议“protocol”一般设置为“0”,就是说在已经确定套接字使用的协议簇和类型时,这个参数的值就为0。
	sockSer = socket(AF_INET, SOCK_STREAM, 0);


	//初始化地址包
	//sin_addr主要用来保存IP地址信息
	//htonl 函数可用于将主机字节顺序中的 IPv4 地址转换为网络字节顺序中的 IPv4 地址。
	addrSer.sin_addr.s_addr = htonl(INADDR_ANY);
	//sin_family主要用来定义是哪种地址族
	addrSer.sin_family = AF_INET;
	//sin_port主要用来保存端口号
	addrSer.sin_port = htons(8000);
	
	// 在建立套接字文件描述符成功后,需要对套接字进行地址和端口的绑定,才能进行数据的接收和发送操作。
	if (bind(sockSer, (SOCKADDR*)&addrSer, sizeof(SOCKADDR)) == SOCKET_ERROR)
	{
		cout << "套接字绑定失败";
		//调用 WSACleanup 时,将取消此过程中任何线程发出的挂起阻止或异步 Windows 套接字调用,
		//而无需发布任何通知消息,也不发出任何事件对象的信号。
		WSACleanup();
	}
	else {
		cout << "绑定套接字成功" << endl;
	}

	//设置监听
	cout << "开始连接" << endl;
	//等待连接最大 0x7fffffff 即32位最大值,成功返回0,失败失败返回SOCKET_ERROR
	if (listen(sockSer, SOMAXCONN) != 0) {
		cout << "监听失败!";
		WSACleanup();
	}
	cout << "监听成功" << endl;


	//接受连接:
	//accept将客户端的信息绑定到一个socket上,
	//也就是给客户端创建一个socket,通过返回值返回给我们客户端的socket
	int addrlen = sizeof(SOCKADDR);
	sockCli = accept(sockSer, (SOCKADDR*) & addrCli, &addrlen);
	if (sockCli == SOCKET_ERROR) {
		cout << "接受连接失败!" << endl;
		WSACleanup();
		return 0;
	}


	cout << "连接建立,准备接受数据" << endl;
	while (true)
	{
		if (recv(sockCli, recvbuf,sizeof(recvbuf), 0)== -1) {
			cout << "接受失败!" << endl;
			break;
		}
		else{
			cout << "客户端消息:" << recvbuf << endl;
		}

		cout << "请输入回复信息:" << endl;
		cin >> sendbuf;
		if (send(sockCli, sendbuf, sizeof(sendbuf), 0)==SOCKET_ERROR)
		{
			cout << "发送失败!" << endl;
			break;
		}
	}

	closesocket(sockSer);
	closesocket(sockCli);
	WSACleanup();
	return 0;


}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119

Client端:

#include <iostream>
using namespace std;
#include <winsock2.h>
#include <WS2tcpip.h>
#pragma comment(lib,"Ws2_32.lib")

const int BUF_SIZE = 2048;			//创建缓冲区
char sendbuf[BUF_SIZE];		//发送缓冲区
char recvbuf[BUF_SIZE];		//接受缓冲区

void initialization()
{
	
	WSADATA wsadata;

	WORD wsaversion = MAKEWORD(2, 2);

	if (WSAStartup(wsaversion, &wsadata) != 0)
	{
		cout << "载入socket库失败" << endl;
	}
	else {
		cout << "初始化成功" << endl;
	}

}

int main()
{
	SOCKET sockCli;	//创建服务器套接字

	//SOCKADDR_IN是系统封装的一个结构体,具体包含了成员变量:sin_family、sin_addr、sin_zero
	SOCKADDR_IN addrSer;

	initialization();

	//创建套接字
	sockCli = socket(AF_INET, SOCK_STREAM, 0);


	//初始化地址包
	//addrSer.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	inet_pton(AF_INET, "127.0.0.1", &addrSer.sin_addr.s_addr);
	addrSer.sin_family = AF_INET;
	addrSer.sin_port = htons(8000);

	

	// 在建立套接字文件描述符成功后,需要对套接字进行地址和端口的绑定,才能进行数据的接收和发送操作。
	if (connect(sockCli, (SOCKADDR*)&addrSer, sizeof(addrSer)) == SOCKET_ERROR)
	{
		cout << "服务器连接失败" << endl;
		WSACleanup();
	}
	else {
		cout << "服务器连接成功" << endl;
	}


	//接受数据:
	while (true)
	{
		cout << "请输入发送信息:" << endl;
		cin >> sendbuf;
		int sendlen = send(sockCli, sendbuf, sizeof(sendbuf), 0);
		if (sendlen < 0) {
			cout << "发送失败!" << endl;
			break;
		}


		int recvlen = recv(sockCli, recvbuf, sizeof(sendbuf), 0);
		
		if (recvlen < 0) {
			cout << "接受失败!" << endl;
			break;
		}
		else {
			cout << "服务端信息:" << recvbuf << endl;
		}

		
		
	}

	closesocket(sockCli);
	WSACleanup();
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/172180
推荐阅读
相关标签
  

闽ICP备14008679号