C++ Windows下Socket通信

现如今,Socket通信已成为主流,想用C++编写Windows下的Socket套接字程序吗?来看看吧。

既然是网络通信,那就必须要有一个客户端(client.cpp)和服务器端(server.cpp)。

要编写Socket套接字程序,那必然要用WinSock2.h和ws2_32.lib(也要用一些其他头文件辅助)。

//导入模块
#include <string>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
//加载lib
#pragma comment(lib, "ws2_32.lib")  //加载 ws2_32.dll
//使用命名空间
using namespace std;

还需要初始化dll和创建套接字:

//初始化dll
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
//           ↑                    ↑
//    WinSock规范的版本号   指向WSAData的指针

//创建套接字
SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
//                      ↑         ↑                  ↑
//              IP地址类型 套接字类型(数据传输方式) 传输协议
//                 IPv4       流格式套接字          TCP传输协议
//注:sock是在cilent.cpp中的,在server.cpp中是servSock(只是变量名不同,其他无异)

接着,server.cpp需要绑定套接字,cilent.cpp需要向服务器(server.cpp)发送请求

sockaddr_in sockAddr; //对象
memset(&sockAddr, 0, sizeof(sockAddr));  //每个字节都变成0
sockAddr.sin_family = PF_INET;  //使用IPv4
sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址(127.0.0.1代表本机)
sockAddr.sin_port = htons(1234);  //端口
//server.cpp
bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR)); //将套接字与IP绑定
//cilent.cpp
connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));

搞了这么多,cilent.cpp的初始化终于搞好了!接下来server.cpp还要进入监听状态和接收客户端的请求:

//进入监听状态
listen(servSock, 20);
//     ↑         ↑
//   套接字 请求队列的最大长度

//接收客户端请求
SOCKADDR clntAddr;
int nSize = sizeof(SOCKADDR);
SOCKET clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize);
//                       ↑               ↑                  ↑
//               服务器端套接字          对象       长度(SOCKADDR的)

接下来,我们要让cilent.cpp不接收服务器端传回的消息,server.cpp要根据用户输入,给cilent.cpp传消息:

//cilent.cpp
while (true)
{
	//接收服务器传回的数据
	char szBuffer[MAXBYTE] = { 0 }; //全部初始化为0
	int can=recv(sock, szBuffer, MAXBYTE, NULL); //接收数据
	string buffer = szBuffer; //转为string(更好用)
	if (buffer == "exit") //退出信号
	{
		printf("对方关闭了Socket。\n"); //提示语
		closesocket(sock); //关闭套接字
		WSACleanup(); //终止使用 DLL
		system("pause"); //等待按下任意键
		exit(0); //退出
	}
	//输出接收到的数据
	printf("从server接收到的数据: %s\n",\
        buffer.size()>2?buffer.substr(1,buffer.size()-1).c_str():""); //server.cpp在数据开头和结尾都加了'k'
}
//server.cpp
while (true)
{
	printf("输入要发送的数据(要退出输入exit):"); //提示语
	//向客户端发送数据
	string str; //好用
	getline(cin, str); //获取一行
	if(str!="exit") //不是退出信号
        send(clntSock,("k"+str+"k").c_str(),str.size()+sizeof(char),NULL); //开头结尾都加'k'再发送
	else //是退出信号
	{
		send(clntSock, "exit", 4 + sizeof(char), NULL); //发送"exit"
		break; //退出循环
	}
}
printf("成功退出!\n"); //提示语
//关闭套接字
closesocket(clntSock);
closesocket(servSock);
WSACleanup();//终止DLL的使用
system("pause"); //按下任意键退出

至此,我们就搞好了通信的程序(很抱歉,只能给本机发消息),现在我给出完整程序:

server.cpp(先运行)

//导入模块
#include <string>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
//加载lib
#pragma comment(lib, "ws2_32.lib")  //加载 ws2_32.dll
//使用命名空间
using namespace std;


int main() {
	//初始化 DLL
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);

	//创建套接字
	SOCKET servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

	//绑定套接字
	sockaddr_in sockAddr;
	memset(&sockAddr, 0, sizeof(sockAddr));  //每个字节都用0填充
	sockAddr.sin_family = PF_INET;  //使用IPv4地址
	sockAddr.sin_addr.s_addr = inet_addr("192.168.101.7");  //具体的IP地址
	sockAddr.sin_port = htons(1234);  //端口
	bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));

	//进入监听状态
	listen(servSock, 20);

	//接收客户端请求
	SOCKADDR clntAddr;
	int nSize = sizeof(SOCKADDR);
	SOCKET clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize);
	while (true)
	{
		printf("输入要发送的数据(要退出输入exit):");
		//向客户端发送数据
		string str;
		getline(cin, str);
		if(str!="exit") send(clntSock, ("k" + str + "k").c_str(), str.size() + sizeof(char), NULL);
		else
		{
			send(clntSock, "exit", 4 + sizeof(char), NULL);
			break;
		}
	}
	printf("成功退出!\n");
	//关闭套接字
	closesocket(clntSock);
	closesocket(servSock);

	//终止 DLL 的使用
	WSACleanup();

	return 0;
}

cilent.cpp(后运行)

//导入模块
#include <string>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <WinSock2.h>
#include <Windows.h>
//加载lib
#pragma comment(lib, "ws2_32.lib")  //加载 ws2_32.dll
//使用命名空间
using namespace std;


int main() {
	//初始化DLL
	WSADATA wsaData;
	WSAStartup(MAKEWORD(2, 2), &wsaData);
	//创建套接字
	SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	//向服务器发起请求
	sockaddr_in sockAddr;
	memset(&sockAddr, 0, sizeof(sockAddr));  //每个字节都用0填充
	sockAddr.sin_family = PF_INET;
	sockAddr.sin_addr.s_addr = inet_addr("192.168.101.7");
	sockAddr.sin_port = htons(1234);
	connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
	while (true)
	{
		//接收服务器传回的数据
		char szBuffer[MAXBYTE] = { 0 };
		int can=recv(sock, szBuffer, MAXBYTE, NULL);
		string buffer = szBuffer;
		if (buffer == "exit")
		{
			printf("对方关闭了Socket。\n");
			//关闭套接字
			closesocket(sock);
			//终止使用 DLL
			WSACleanup();
			system("pause");
			return 0;
		}
		//输出接收到的数据
		printf("从server接收到的数据: %s\n", buffer.size() > 2 ? buffer.substr(1, buffer.size() - 1).c_str() : "");
	}
	return 0;
}

虽然功能有限,但毕竟是可以通信的,如果你有两台(或以上)Windows电脑,就可以通过改动IP地址来通信。

最后,强烈建议自己把代码删了再敲一遍,检验有没有学透!

Windows平台上使用C++编写Socket套接字程序需要包含一些头文件和链接相应的库文件。首先,需要包含以下头文件: #include <string> #include <cstdio> #include <cstdlib> #include <iostream> #include <WinSock2.h> #include <Windows.h> 然后,需要链接ws2_32.lib库文件,可以使用#pragma comment(lib, "ws2_32.lib")来实现。 在服务器端(server.cpp)中,需要进行套接字的绑定操作。可以使用sockaddr_in结构体来指定套接字的IP地址和端口号,并使用bind函数将套接字与IP地址绑定: sockaddr_in sockAddr; memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.sin_family = PF_INET; sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); sockAddr.sin_port = htons(1234); bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR)); 在客户端端(client.cpp)中,需要向服务器发送请求。可以使用connect函数将套接字与服务器的IP地址和端口号连接起来: sockaddr_in sockAddr; memset(&sockAddr, 0, sizeof(sockAddr)); sockAddr.sin_family = PF_INET; sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); sockAddr.sin_port = htons(1234); connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR)); 接下来,在客户端(client.cpp)中,可以使用循环来接收服务器端传回的消息。使用recv函数接收数据,并将接收到的数据转换为string类型进行处理。如果接收到的数据是"exit",则表示对方关闭了Socket,程序需要退出。否则,可以输出接收到的数据。 while (true) { char szBuffer\[MAXBYTE\] = { 0 }; int can = recv(sock, szBuffer, MAXBYTE, NULL); string buffer = szBuffer; if (buffer == "exit") { printf("对方关闭了Socket。\n"); closesocket(sock); WSACleanup(); system("pause"); exit(0); } printf("从server接收到的数据: %s\n", buffer.size() > 2 ? buffer.substr(1, buffer.size() - 1).c_str() : ""); } 在服务器端(server.cpp)中,也可以使用循环来根据用户输入给客户端传消息。使用send函数将消息发送给客户端。如果用户输入的是"exit",则表示要退出程序。 while (true) { printf("输入要发送的数据(要退出输入exit):"); string str; getline(cin, str); if (str != "exit") send(clntSock, ("k" + str + "k").c_str(), str.size() + sizeof(char), NULL); else { send(clntSock, "exit", 4 + sizeof(char), NULL); break; } } printf("成功退出!\n"); closesocket(clntSock); closesocket(servSock); WSACleanup(); system("pause"); 以上是一个简单的C++ Windows Socket套接字程序的示例。通过使用WinSock2.h和ws2_32.lib库文件,可以实现Socket通信功能。 #### 引用[.reference_title] - *1* *2* *3* [C++ WindowsSocket通信](https://blog.csdn.net/m0_66248056/article/details/128450302)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值