windows网络进阶之listen参数含义

news2024/12/24 2:41:47

目录

        一、前言

二、listen参数

三、实战案例

1. 使用Sleep函数让线程暂停 

2. 案例代码展示

3. 编译生成exe文件        


一、前言

        一、前言

        在Windows网络编程中,在使用TCP时,listen函数它是一个重要的关键的步骤,使得套接字能够接收传入的连接请求,下面我主要通过实战案例讲解listen参数的含义。注:本章是一个进阶篇,前提是能够掌握基础windows网络编程概念。

二、listen参数

        listen 函数官方给的原型为:

int listen(SOCKET s, int backlog);

         这里有两个参数:

        1.SOCKET s

        这是一个已绑定(通过bind函数)的套接字,作用用于接收客户端的连接请求。这个参数比较好理解,我们重点讲解第二个参数。

        2.int backlog

        这是一个 int 类型的变量,官方给的解释为:挂起的连接队列的最大长度。

        通俗意义上来理解为:就是当一个客户端尝试连接到服务器时,如果服务器当前正忙于处理其他连接,那么这个连接请求会被放入一个队列中等待。而这个队列的能允许承受的最大大小为blcklog的大小决定。

        上面就是对 backlog 的解释,但是讲到这里,应该有很少人能够真正理解它的含义所在,下面我将要通过一个实战案例带你真正的体验它的作用。

三、实战案例

1. 使用Sleep函数让线程暂停 

        我们要展现 backlog 数字的效果,就必须让多个客户端来连接同一个服务器。而正常情况下,客户端在连接服务器发送消息后就断开连接了。此时的挂起队列长度最大一直为1,所以我们需要让服务器成功监听客户端后,客户端不会断开连接。

        这里我使用了一个 Sleep 函数让服务器监听成功后线程暂停在这里,代码如下:

    // 3. 监听
	if (listen(sockSrv, 5) == SOCKET_ERROR) // 5 是指最大的监听数目,执行到listen
	{

		printf("listen error = %d\n", GetLastError());
		return -1; 
	}
	printf("delay 20 begin\n");
	Sleep(20000);
	printf("delay 20 end\n");

         上述代码是TCP服务器端代码的片段,这里我设置 backlog 为 5 ,在监听后程序暂停休眠 20 秒,程序开始启动,同时对 listen 函数进行错误判断,方面我们能过直观的观察错误。

2. 案例代码展示

        服务器端总代码:

#include <stdlib.h>
#include <winsock.h>
#include <stdio.h>
#include <iostream>

#pragma comment(lib, "ws2_32.lib")

int main()
{

	printf("NetWork socket\n");
#if 1
	// 0 初始化网络库
	// 初始化库
	WSADATA wsaData;
	int stu = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (stu != 0) {
		std::cout << "WSAStartup 错误:" << stu << std::endl;
		return 0;
	}
#endif

	// 1. 安装电话机 socket
	SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0);

	if (sockSrv == INVALID_SOCKET)
	{
		std::cout << "socket failed!" << GetLastError() << std::endl;
		WSACleanup(); //释放Winsock库资源
		return 1;
	}
	
	// 2, 分配电话号码
	SOCKADDR_IN addrSrv;
	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);   // 地址 IP地址any
	addrSrv.sin_family = AF_INET;    // ipv4协议
	addrSrv.sin_port = htons(6000);  // 端口号

	bind(sockSrv, (sockaddr *)&addrSrv, sizeof(SOCKADDR));

	// 3. 监听
	if (listen(sockSrv, 5) == SOCKET_ERROR) // 5 是指最大的监听数目,执行到listen
	{

		printf("listen error = %d\n", GetLastError());
		return -1; 
	}
	printf("delay 20 begin\n");
	Sleep(20000);
	printf("delay 20 end\n");

	// 客户端的信息
	SOCKADDR_IN addrCli;
	int len = sizeof(SOCKADDR);


	while (true)
	{
		printf("begin accept\n");
		// 4. 分配一台分机去处理客户端的连接
		SOCKET sockCon = accept(sockSrv, (sockaddr*)&addrCli, &len);

		// 定义发送多个消息
		char sendBuff[100] = { 0 };
		//sprintf_s(sendBuff, 100, "Hello World", inet_ntoa(addrCli.sin_addr));
		sprintf_s(sendBuff, 100, "Hello World");


		// 5. 开始通话,发送信息
		int iLen = send(sockCon, sendBuff, strlen(sendBuff), 0);

		// 6. 接收数据
		char recvBuff[100] = { 0 };
		recv(sockCon, recvBuff, 100, 0);

		printf("recvBuf = %s\n", recvBuff);
		closesocket(sockCon);
	}

	// 7.关闭服务器端
	closesocket(sockSrv);
	// 清理库
	WSACleanup();
	system("pause");
	return 0;
}

         客户端总代码:


#include <stdlib.h>
#include <winsock.h>
#include <stdio.h>
#include <iostream>
#pragma comment(lib, "ws2_32.lib")

int main()
{
	printf("NetWork socket\n");
#if 1
	// 0 初始化网络库
	WSADATA wsaData;
	int stu = WSAStartup(MAKEWORD(2, 2), &wsaData);
	if (stu != 0) {
		std::cout << "WSAStartup 错误:" << stu << std::endl;
		return 0;
	}
#endif

	// 1. 安装电话机 socket
	SOCKET sockCli = socket(AF_INET, SOCK_STREAM, 0);

	if (sockCli == INVALID_SOCKET)
	{
		std::cout << "socket failed!" << GetLastError() << std::endl;
		WSACleanup(); //释放Winsock库资源
		return 1;
	}

	// 2, 配置IP地址 和 端口号
	SOCKADDR_IN addrSrv;
	addrSrv.sin_family = AF_INET;    // ipv4协议
	addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.1.7"); // 地址 IP地址any
	addrSrv.sin_port = htons(6000);  // 端口号

	// 3. 连接服务器
	int res = connect(sockCli, (sockaddr*)&addrSrv, sizeof(sockaddr));
	if (res == SOCKET_ERROR)
	{

		printf("connect error = %d\n", GetLastError());
		system("pause");
		return -1;
	}

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

	printf("接收到的数据%s\n", recvBuff);

	const char sendBuff[100] = "asdasda";
	send(sockCli, (char*)sendBuff, 100, 0);

	// 5.  关闭连接
	closesocket(sockCli);

	// 清理库 
	WSACleanup();
	system("pause");
	return 0;
} 

3. 编译生成exe文件
        

        第一步: 分别编译生成服务器端可执行代码和客户端可执行代码,操作步骤如图:

         

        编译成功如图所示。 

        第二步,在 debug 文件中夹种找到 exe 可执行文件。文件路径如图:

         

       第三步:先启动服务器程序,然后启动多个客户端器程序。多个客户端程序结果如图所示:

        最后总结,可见当启动第六个客户端程序时,出现错误   connect error = 10061 , 错误查找结果为:由于目标计算机积极拒绝,无法连接。说明超出了挂起的连接队列的最大长度,客户端无法连接。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1885052.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】使用C++在线程中动态记录数据到外部文件

在现代软件开发中&#xff0c;多线程编程已成为处理并发任务、提高程序性能的重要手段。而在多线程环境下&#xff0c;如何有效地管理和记录数据&#xff0c;尤其是将动态生成的数据安全地写入外部文件&#xff0c;是许多应用程序必须面对的问题。本文将深入探讨如何在C中使用多…

FastApi中的常见请求类型

FastApi中的常见请求类型 后端开发语言中&#xff0c;我钟情于node&#xff0c;高效的异步处理真是让我眼前一亮&#xff0c;同时&#xff0c;简单易懂的语法也让我非常倾心 但是但是&#xff0c;因为考虑要写一个深度学习算法的后端接口&#xff0c;所以不得不选用python作为…

传神论文中心|第15期人工智能领域论文推荐

在人工智能领域的快速发展中&#xff0c;我们不断看到令人振奋的技术进步和创新。近期&#xff0c;开放传神&#xff08;OpenCSG&#xff09;社区发现了一些值得关注的成就。传神社区本周也为对AI和大模型感兴趣的读者们提供了一些值得一读的研究工作的简要概述以及它们各自的论…

【linux】虚拟机安装 BCLinux-R8-U4-Server-x86_64

目录 一、概述 1.1移动云Linux系统订阅服务 CLS 1.2 大云天元操作系统BC-Linux 二、安装 一、概述 1.1移动云Linux系统订阅服务 CLS 移动云Linux系统订阅服务 CLS &#xff08;Cloud Linux Service&#xff09;为使用BC-Linux操作系统的用户提供标准维保服务以及高级技术支…

JVM原理(九):JVM虚拟机工具之可视化故障处理工具

1. JHSDB:基于服务性代理的调试工具 JHSDB是一款基于服务性代理实现的进程外调试工具。 服务性代理是HotSpot虚拟机中一组用于映射Java虚拟机运行信息的、主要基于Java语言实现的API集合。 2. JConsole:Java监视与管理控制台 JConsole是一款基于JMX的可视化监视、管理工具。…

矩阵、混剪、大盘,3大功能升级优化!助力企业高效管理!

在数字化转型的浪潮中&#xff0c;企业对于工具与技术的需求愈发强烈。 为满足市场需求&#xff0c;本月【云略】为各企业上线了便捷功能&#xff0c;赋能企业经营决策和业务增长。 矩阵管理 √【矩阵号管理】抖音支持设置城市IP 内容管理 √【混剪任务】支持关联智能发布计…

模拟 ADC 的前端

ADC 的 SPICE 模拟 反复试验的方法将信号发送到 ADC 非常耗时&#xff0c;而且可能有效也可能无效。如果转换器捕获电压信息的关键时刻模拟输入引脚不稳定&#xff0c;则无法获得正确的输出数据。SPICE 模型允许您执行的步是验证所有模拟输入是否稳定&#xff0c;以便没有错误…

百家讲坛 | 裴伟伟:企业中安全团队应当如何反馈漏洞

作者简介&#xff1a;裴伟伟&#xff0c;洞源实验室创始人&#xff0c;国家网安基地网络安全行业专家&#xff0c;网安加社区特聘专家&#xff0c;持有CISSP、PMP证书&#xff0c;曾在HITCON、可信云大会、开源产业大会等安全论坛发表演讲。曾任国内某安全实验室负责人、某互金…

3.js - 色调映射(renderer.toneMapping)

// ts-nocheck// 引入three.js import * as THREE from three// 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls// 导入lil.gui import { GUI } from three/examples/jsm/libs/lil-gui.module.min.js// 导入tween import * as TWEEN…

Stable DIffusion 线稿上色+风格迁移教程,建议收藏!

前言 Stable Diffusion 线稿上色与风格迁移教程。 欢迎来到Stable Diffusion的线稿上色与风格迁移教程&#xff01;在这个教程中&#xff0c;我们将引导你如何使用Stable Diffusion技术&#xff0c;将你的线稿作品进行上色&#xff0c;并迁移到不同的艺术风格。让我们开始吧&a…

双端队列广搜——AcWing 175. 电路维修

双端队列广搜 定义 双端队列广搜&#xff08;Breadth-First Search with a Deque&#xff09;是一种图或树的遍历算法变体&#xff0c;它利用了双端队列&#xff08;Deque&#xff0c;全称Double Ended Queue&#xff0c;允许在其两端进行插入和删除操作&#xff09;作为数据…

CentOS7源码安装nginx并编写服务脚本

华子目录 准备下载nginx源码包关闭防火墙关闭selinux安装依赖环境 解压编译安装测试编写服务脚本&#xff0c;通过systemctl实现服务启动与关闭测试 准备 下载nginx源码包 在源码安装前&#xff0c;我们得先下载nginx源码包https://nginx.org/download/这里我下载的是nginx-1…

PHP景区旅游多商户版微信小程序系统源码

解锁景区新玩法&#xff01;​ 引言&#xff1a;一站式旅行新体验 厌倦了传统景区的单调游览&#xff1f;想要一次旅行就能体验多种风情&#xff1f;那么&#xff0c;“景区旅游多商户版”绝对是你的不二之选&#xff01;这个创新模式将景区内多个商户资源整合&#xff0c;为…

Golang-context理解

golang-context笔记整理 golang为何设计context&#xff1f;代码上理解原理空context类cancelCtx类.withcancelctx方法 timerCtx类valueCtx类 golang为何设计context&#xff1f; 有并发特性的语言中&#xff0c;都会有一种说法&#xff1a;创建异步线程或者携程的时候&#x…

【Altium】如何处理PCB上所有焊盘被误盖油

【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 解决焊盘被误盖油的操作 2、 问题场景 所有焊盘都可以设置为盖油或不盖油&#xff0c;由于焊盘需要用来焊接元器件&#xff0c;所以都不会设置盖油。由于误操作或者创建封装时设置错误&#xff0c;造成一定数量的焊盘…

【GD32】07 - UART串口通信

GD32F407中的UART 今天我用的型号是GD32F407&#xff0c;用其他型号的小伙伴在使用UART的时候注意一下自己手上板子的资源就行&#xff0c;我们使用固件库就算是不同型号其实也是没有什么太大差别的。 我们废话不多说&#xff0c;直接开始讲怎么使用UART。 首先我们先确定串…

【面试干货】Static关键字的用法详解

【面试干货】Static关键字的用法详解 1、Static修饰内部类2、Static修饰方法3、Static修饰变量4、Static修饰代码块5、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java编程语言中&#xff0c;static是一个关键字&#xff0c;它可…

猫头虎博主全栈前沿AI技术领域矩阵社群

猫头虎博主全栈前沿AI技术领域矩阵社群 &#x1f44b;大家好&#xff0c;我是猫头虎&#xff01;今天我要向大家介绍一个非常重要的社群矩阵——专为全栈前沿AI技术领域的朋友们打造的各种技术交流和资源互助的社群。这些社群不仅能帮助大家快速提升技术水平&#xff0c;还能拓…

深度学习笔记: 最详尽解释混淆矩阵 Confusion Matrix

欢迎收藏Star我的Machine Learning Blog:https://github.com/purepisces/Wenqing-Machine_Learning_Blog。如果收藏star, 有问题可以随时与我交流, 谢谢大家&#xff01; 混淆矩阵 假设我们有包含临床测量数据的医疗数据&#xff0c;例如胸痛、良好的血液循环、动脉阻塞和体重…

LeetCode 子集

原题链接78. 子集 - 力扣&#xff08;LeetCode&#xff09; 这是一道暴力搜索问题参考大佬们的题解&#xff0c;对这类题目做出一下总结 1.确定递归参数变量 2.递归结束条件 3.做出选择&#xff0c;递归调用进入下一层 4.回溯&#xff0c;返回到递归前的状态 要完成前面这…