C++网络编程---TCP服务器端控制台创建

一、网络编程的必要文件

网络编程头文件 #include <WinSock2.h>
#pragam comment(lib,“ws2_32.lib”)
c语言头文件 #include <stdio.h> #include <stdlib.h>

二、初始化套接字库,也是服务器和客户端能够连接成功的网络库

WORD wVersionRequested;// WORD(unsigned short) 定义了一个 WORD 类型的变量 wVersionRequested,用来存储请求的 Winsock 版本信息。
WSADATA wsaData;//定义了一个 WSADATA 结构体变量 wsaData,用来接收 Winsock 启动信息
wVersionRequested = MAKEWORD(2, 2);//使用 MAKEWORD() 宏将 Winsock 版本号设置为 2.2,表示请求使用 Winsock 2.2 版本。
int err = WSAStartup(wVersionRequested, &wsaData);//调用 WSAStartup() 函数初始化 Winsock 库,函数返回值将存储在 err 变量中
WSACleanup();//关闭网络库

三、创建TCP套接字

TCP(Transmission Control Protocol)套接字是一种在网络编程中常用的通信机制。在TCP/IP协议中,TCP负责提供可靠的、面向连接的通信服务,而套接字(socket)则是在应用层和传输层之间的接口,用于实现网络通信。
SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0);
AF_INET:指定了地址族,表示 IPv4 地址族,用于指定套接字的地址格式。
SOCK_STREAM:指定了套接字的类型,表示这是一个面向连接的、可靠的、基于流的 TCP 套接字。
0:表示默认协议,对于 TCP 套接字来说,通常为 0。
closesocket(sockSrv);//关闭套接字

四、分配地址和端口

SOCKADDR_IN addrSrv;//定义了一个 SOCKADDR_IN 结构体变量 addrSrv,用来存储服务器的地址信息,包括 IP 地址和端口号。
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);// 设置服务器的 IP 地址。INADDR_ANY 表示服务器将会绑定到所有可用的网络接口上,即监听所有网络接口的连接请求。htonl() 函数用于将主机字节序转换为网络字节序。
addrSrv.sin_family = AF_INET;//设置地址族为 IPv4,表示服务器地址采用 IPv4 地址格式。
addrSrv.sin_port = htons(6000);//设置服务器的端口号为 6000,htons() 函数用于将主机字节序的端口号转换为网络字节序。

五、绑定地址

bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR_IN));//套接字 sockSrv 将会与之前设置好的地址信息 addrSrv 进行绑定,这样服务器就会在指定的 IP 地址和端口上监听连接请求。在网络编程中,bind 函数通常用于将套接字与特定的 IP 地址和端口号绑定,以便服务器能够接收客户端的连接请求。

六、服务器端监听客户端请求

listen(sockSrv, 5);//5:表示允许同时连接到这个套接字的最大客户端数量,也被称为backlog。在这种情况下,服务器套接字将开始监听连接请求,并且最多允许 5 个客户端排队等待被接受。

七、接收或者发送客户端的消息

//创建可以保存客户端信息的套接字
SOCKADDR_IN addrCli;//用来存储客户端的地址信息。
int len = sizeof(SOCKADDR);//地址信息的大小
SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrCli, &len); //服务器套接字 sockSrv 调用 accept 函数来接受客户端的连接请求。一旦有客户端连接进来,accept 函数会返回一个新的套接字 sockConn,用于与客户端进行通信。同时,客户端的地址信息会存储在 addrCli 中,len 会被更新为客户端地址信息的实际大小。
int msg_size = recv(sockConn, recvBuf, 100, 0); //调用 recv 函数从已连接的套接字 sockConn 中接收数据,并将接收到的数据存储在 recvBuf 中。
sockConn:已连接的套接字,用于与客户端进行通信。
recvBuf:用于存储接收到的数据的缓冲区。
100:要接收的最大字节数,这里是 100 字节。
0:接收数据的标志位,通常设为 0。
msg_size 表示实际接收到的数据的字节数。如果返回值为 0,则表示客户端已关闭连接;如果返回值为 SOCKET_ERROR,则表示接收数据时出现错误。

int msg_size= send(sockConn, sendBuf, strlen(sendBuf),0);//调用 send 函数向已连接的套接字 sockConn 发送数据,发送的数据来自 sendBuf 缓冲区。
sockConn:已连接的套接字,用于与客户端进行通信。
sendBuf:要发送的数据的缓冲区。
strlen(sendBuf):要发送的数据的长度,通过 strlen 函数获取 sendBuf 中的字符串长度。
0:发送数据的标志位,通常设为 0。
msg_size表示实际发送的数据的字节数。如果返回值为 SOCKET_ERROR,则表示发送数据时出现错误。

//头文件和库
#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#pragma comment(lib,"ws2_32.lib")

//主函数入口,开启控制台
int main()
{
	printf("Tcp Server\n");
	//0初始化网络库
	WORD wVersionRequested;                                                                                                                                                      
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD(2, 2);
	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0)
	{
		printf("WSAStartuo errorNum = %d\n", GetLastError());
		return err;
	}
	if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
	{
		printf("LOBYTE errorNum = %d\n", GetLastError());
		WSACleanup();
		return -1;
	}

	//1安装TCP套接字
	SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0);
	if (INVALID_SOCKET == sockSrv)
	{
		printf("socket errornum = %d\n", GetLastError());
		return -1;
	}

	//2分配地址和端口
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6000);
	//绑定地址和端口
	if (SOCKET_ERROR == bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR_IN)))
	{
		printf("bind error = %d\n", GetLastError());
		return -1;
	}
	
	//3监听客户端
	if (SOCKET_ERROR == listen(sockSrv, 5))//客户端队列有5个,先进先出
	{
		printf("listen error = %d\n", GetLastError());
		return -1;
	}
	//存储客户端的地址和端口信息
	SOCKADDR_IN addrCli;
	int len = sizeof(SOCKADDR);

	//4等待接收客户端信息、发送信息给客户端
	while (true)
	{
		// 阻塞在这句代码,等待接收
		SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrCli, &len);//阻塞的位置 
		//5服务器发信息
		char sendBuf[100] = { 0 };
		//sprintf_s(sendBuf, 100, "welcome %s to china",inet_ntoa(addrCli.sin_addr));
		sprintf_s(sendBuf, 100, "我是服务器,请客户端接收!");
		int iLen = send(sockConn, sendBuf, strlen(sendBuf),0);
		
		//服务器接收信息
		char recvBuf[100] = { 0 };
		iLen = recv(sockConn, recvBuf, 100, 0);
		printf("recvBuf = %s", recvBuf);

		//6关闭存储客户端信息的套接字
		closesocket(sockConn);
	}
	//7关闭服务器套接字
	closesocket(sockSrv);

	//8释放网络库
	WSACleanup();

	system("pause");
	return 0;
}

TCP服务器控制台,等待客户端的信息

  • 40
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值