带你深入浅出之Windows编程:一、史上最简单之TCP服务端-客户端的创建

此为Windows编程的第谈!关注我,带你快速通过Windows编程的学习路线

每一篇的技术点都是很很重要!很重要!很重要!但不冗余!

我们通常采取总-分-总生活化的讲解方式来阐述一个知识点!

码农不易,各位学者学到东西请点赞支持支持

开始部分:

总:首先,我们要了解流程(根据此图来理解,并记忆此图)

分:

一、服务端:

1.首先我们是需要初始化Winsock库的:服务器使用WSAStartup函数来初始化Winsock库。此步骤是必须的。就比如电信公司架设电话网络,确保通信的基础设施到位。

2.创建套接字:使用socket函数创建一个TCP套接字。这个套接字用来监听客户端的连接请求。

相当于在公司安装一部电话机,这部电话机可以用来接听客户的电话。

3.bind绑定套接字:将套接字绑定到本地的一个特定的IP地址和端口。相当于给公司的电话机分配一个固定的电话号码,这个号码可以接收来自任何地方的电话。

4.listen监听使用listen函数使套接字进入监听状态,并指定连接请求的队列长度。相当于公司把电话机设定为接听模式,随时准备接听客户打来的电话。

5.接受连接:服务器进入一个无限循环,使用accept函数来接收客户端的连接,一旦有客户端连接请求到达,accept函数会返回一个新的套接字,这个套接字专门用于与这个客户端通信。

公司电话响了(客户打电话过来了),接线员接起电话,准备与客户沟通。

6.发送欢迎消息:使用send函数向客户端发送一条“Welcome to China”信息。

接线员在接通电话后说“欢迎致电我们公司”。

7.接受信息:使用recv函数接收客户端发送的信息。

接线员听客户说话,记录客户的需求或问题。

8.关闭套接字:通信完成后,关闭为客户端创建的专用套接字。

通话结束后,接线员挂断电话,但电话机继续保持接听模式,准备接听下一个客户的电话。

根据上面的步骤,服务端的代码实现如下:

#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#include <ws2tcpip.h> // 包含inet_ntop的头文件

#pragma comment(lib, "Ws2_32.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("WSAStartup 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.安装电话机
	SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);
	if (INVALID_SOCKET == sockSrv)
	{
		printf("socket error = %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)))
	{
		printf("bind error = %d\n", GetLastError);
		return -1;
	}
	

	// 3.监听
	if (SOCKET_ERROR == listen(sockSrv, 5))
	{
		printf("listen error = %d\n", GetLastError);
		return -1;
	}
	listen(sockSrv, 5);
	SOCKADDR_IN addrCli;
	int len = sizeof(SOCKADDR);

	while (TRUE)
	{
		// 4.分配一台分机去处理客户端连接,拿起电话机,准备接听
		printf("begin accept\n");
		SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrCli, &len);
		printf("end accept\n");
#define _WINSOCK_DEPRECATED_NO_WARNINGS // 禁用弃用警告
		char sendBuf[100] = { 0 };
		// 替换为inet_ntop
		inet_ntop(AF_INET, &addrCli.sin_addr, sendBuf, sizeof(sendBuf));
		sprintf_s(sendBuf, 100, "Welcome %s to China", sendBuf);

		// 5.开始通话,发收数据
		int iLen = send(sockConn, sendBuf, strlen(sendBuf), 0);

		char recvBuf[100] = { 0 };
		iLen = recv(sockConn, recvBuf, 100, 0);

		printf("recvBuf = %s\n", recvBuf);

		// 6.关闭分机
		closesocket(sockConn);
	}
	// 7.关闭总机,这里不应该关闭sockSrv,因为sockSrv是服务端监听的套接字
	// closesocket(sockSrv);

	WSACleanup(); // 清理Winsock
	return 0;
}

二、客户端:

1.初始化Winsock库:客户端也是使用WSAStartup函数来初始化Winsock库。

相当于在家里安装电话网络,确保可以打电话。

2.创建套接字:也是使用socket函数创建一个TCP套接字,这个套接字用于连接服务器。

在家里安装一部电话机,这部电话机可以用来拨打电话。

3.配置服务器的地址:

相当于查找公司的电话号码并输入到电话机中,准备拨号。

4.连接服务器:使用connect函数连接到服务器。

按下拨号键,开始拨打公司的电话号码。

5.接收欢迎信息:连接建立后,使用recv函数来接收服务器的欢迎信息。

电话接通后,听到接线员说“欢迎致电我们公司”。

6.发送响应信息:使用send函数向服务器发送一条响应信息。

客户向接线员说明自己的需求或问题。

7.关闭套接字:通信完成后,关闭套接字。

通话结束后,客户挂断电话。

根据上面的步骤,客户端的代码实现如下:

#include <stdio.h>
#include <stdlib.h>
#include <WinSock2.h>
#include <ws2tcpip.h> // 包含inet_ntop的头文件

#pragma comment(lib, "Ws2_32.lib") // 链接Ws2_32.lib


int main()
{


	printf("TCP Client\n");

	//0.初始化网络库

	WORD wVersionRequested;
	WSADATA wsaData;
	int err;
	wVersionRequested = MAKEWORD(2, 2);
	err = WSAStartup(wVersionRequested, &wsaData);
	if (err != 0)
	{
		printf("WSAStartup 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.安装电话机
	SOCKET sockCli = socket(AF_INET, SOCK_STREAM, 0);
	if (INVALID_SOCKET == sockCli)
	{
		printf("socket error = %d\n", GetLastError());
		return -1;
	}

	//2.配置要连接的服务器
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.0.102");
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(6000);


	//3.连接服务器
	if (SOCKET_ERROR == connect(sockCli, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)))
	{
		printf("connect error = %d\n", GetLastError());
		system("pause");
		return -1;
	}

	//4.收发数据
	char recvBuf[100] = { 0 };
	int iLen = recv(sockCli, recvBuf, 100, 0);

	printf("recvBuf = %s\n", recvBuf);

	char sendBuf[100] = "love is not only";
	iLen = send(sockCli, (char*)sendBuf, 100, 0);

	//5.关闭套接字
	closesocket(sockCli);

	system("pause");



}

总:客户端和服务端的代码其实是类似的。

  学习链接:https://xxetb.xetslk.com/s/3Kif2D

  • 16
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值