C++打造局域网聊天室第七课: Socket编程初步2

news2025/2/23 2:21:53

文章目录

  • 前言
  • 一、Socket的API函数
  • 二、服务端建立Socket步骤
  • 总结


前言

C++打造局域网聊天室第七课: Socket编程初步2


一、Socket的API函数

接着上一课的内容,我们在chartroom.cpp中找到如下位置
在这里插入图片描述
插入断点,运行
在这里插入图片描述
运行到断点处后,按F11可以进入该函数内部
在这里插入图片描述
可以看到其调用了函数WSAStartup函数,进行了Socket库的初始化操作。

二、服务端建立Socket步骤

当用户点击开启服务器按钮时进行服务器端的开启,利用MFC消息映射机制建立该按钮的单击后需要的执行功能函数,同样会自动生成头文件中的函数声明,源文件中的函数实现框架,具体步骤见MFC消息映射机制
在这里插入图片描述
建立一个监听的Socket,在chartroomDlg.h头文件中声明变量。
在这里插入图片描述
然后在chartroomDlg.cpp源文件中构造函数处进行初始化,INVALID_SOCKET为一个宏,被定义为-1,表示一个不存在的Socket值。
在这里插入图片描述
之后在OnBnClickedButton3()函数实现中进行服务器端建立Socket函数实现。具体代码见如下代码块,各行代码的意义见注释。

void CchartroomDlg::OnBnClickedButton3()
{
	// TODO: 在此添加控件通知处理程序代码
	//新建:调用socket函数新建Socket,第一个参数为协议族,利用IPV4就用该参数;第二个和第三个参数为建立流式套接字;函数成功会返回一个Socket,
	//用作监听的Socket,用于监听某一个端口。
	m_ListenSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (m_ListenSock == INVALID_SOCKET) // 如果新建失败
	{
		AfxMessageBox(_T("新建SOCKET失败!"));
		return;
	}
	// 绑定:将新建的socket绑定在本机新建的一个IP和端口上,是在用户界面本地监听端口处动态获取的
	UINT uPort = GetDlgItemInt(IDC_EDIT7); //GetDlgItemText函数取得字符串,GetDlgItemInt函数取得整数
	if (uPort <= 0 || uPort > 65535) // 对端口值进行判断
	{
		AfxMessageBox(_T("请输入合适的端口:1-65535"));
		goto __Error_End;
	}
	sockaddr_in service;
	service.sin_family = AF_INET; //与新建socket第一个参数的值一样
	service.sin_addr.s_addr = INADDR_ANY; //获取本机所有可能得到的IP,一般有几块网卡就有几个IP
	//cout << service.sin_addr.s_addr;
	service.sin_port = htons(uPort); //将端口传递给sin_port成员,htons为字节顺序转换函数,利用该函数是因为常用的CUP字节顺序与网络字节顺序相反
	// 例如地址0x12345678,host:0x78 0x56 0x34 0x12; net:0x12 0x34 0x56 0x78。h为host(主机),n为network。htons即为将主机的字节顺序转化为net顺序

	if (bind(m_ListenSock, (sockaddr*)&service, sizeof(sockaddr_in)) == SOCKET_ERROR)
		// 第一个参数为需要绑定的socket;第二个参数为一个sockaddr_in结构,需要进行一个强制类型转换;第三个参数为该结构的大小
	{
		AfxMessageBox(_T("绑定端口失败!"));
		goto __Error_End;
	}

	// 监听:第一个参数为传递的socket,第二个参数为监听序列中允许同时存在的客户端最大数目
	if (listen(m_ListenSock, 5) == SOCKET_ERROR)
	{
		AfxMessageBox(_T("监听失败!"));
		goto __Error_End;
	}

	// 接受客户端的连接:
	sockaddr_in clientAddr;
	int iLen = sizeof(sockaddr_in);
	// 第一个参数为socket,第二个参数为一个sockaddr_in结构,需要进行一个强制类型转换,第三个参数为该结构的大小的地址。
	// 返回的socket为服务端与接受的客户端通信的socket,即利用accsocket进行与其他客户端的通信,m_ListenSock只是在服务器端进行监听
	SOCKET accSock = accept(m_ListenSock, (struct sockaddr *)&clientAddr , &iLen);
	if (accSock == INVALID_SOCKET)
	{
		AfxMessageBox(_T("接受客户端失败"));
		goto __Error_End;
	}

	//其他操作
	
	// 出现错误则关闭监听,退出函数
__Error_End:
	closesocket(m_ListenSock);
}

但是目前来说,点击开启服务器会使得程序崩溃,卡死。只能通过终止调试按钮停止程序。
在这里插入图片描述
在这里插入图片描述
这就涉及到了另外的知识点:阻塞与非阻塞。
阻塞是指干不完活不回来,在那里堵住了,这样的话调用阻塞函数的线程被挂起。该程序阻塞在了accept函数那里,使得主线程被挂起。比如WinSocket API中的accept、send等函数就是阻塞的。阻塞类似于C++中的cin函数,如果用户不输入的话程序不会向下执行,会卡在那里。
非阻塞是指你先干活,我先不干这个活,你干完了我再来

阻塞特点:使用简单但是效率低
非阻塞特点:使用复杂,一些socket API函数执行后总是马上返回WSAEWOULDBLOCK错误,表明请求的操作没有成功完成,如果循环检查的话知道有信息到达,效率肯定会降低,也不易于新手使用

可以使用Windows提供的各种异步I/O模型进行解决,在下节课中介绍。


总结

C++打造局域网聊天室第七课: Socket编程初步2

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

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

相关文章

vue-router路由传参的两种方式(params 和 query )

一、vue-router路由传参问题 1、概念&#xff1a; A、vue 路由传参的使用场景一般应用在父路由跳转到子路由时&#xff0c;携带参数跳转。 B、传参方式可划分为 params 传参和 query 传参&#xff1b; C、而 params 传参又可分为在 url 中显示参数和不显示参数两种方式&#x…

Docker Compose应用实战

文章目录 1、使用Docker Compose必要性及定义2、Docker Compose应用参考资料3、Docker Compose应用最佳实践步骤1_概念2_步骤 4、Docker Compose安装5、Docker Compose应用案例1_网站文件准备2_Dockerfile文件准备3_Compose文件准备4_使用docker-compose up启动容器5_访问6_常见…

el-table组件树形数据修改展开箭头

<style lang"scss" scoped> ::v-deep .el-table__expand-icon .el-icon-arrow-right:before {content: ">"; // 箭头样式font-size: 16px; }::v-deep .el-table__expand-icon{ // 没有展开的状态background-color: rgba(241, 242, 245, 1);color:…

5.2 JavaScript 案例 - 轮播图

JavaScript - 轮播图 文章目录 JavaScript - 轮播图基础模版一、刷新页面随机轮播图案例二、轮播图 定时器版三、轮播图完整版 基础模版 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"…

MongoDB与阿里云庆祝合作五周年,展望AI赋能新未来

12月3日&#xff0c;在印尼举行的阿里云合作伙伴大会2024上&#xff0c;MongoDB荣膺阿里云“2024技术创新成就奖”&#xff0c;该奖项旨在表彰与阿里云保持长期稳定合作&#xff0c;通过深度技术融合&#xff0c;在产品技术创新、行业区域深耕等领域取得卓越成就的伙伴。自2019…

数据结构(Queue队列)

前言&#xff1a; 在计算机科学中&#xff0c;数据结构是构建高效算法和程序的基础&#xff0c;而队列&#xff08;Queue&#xff09;作为一种经典的线性数据结构&#xff0c;具有重要的地位。与栈&#xff08;Stack&#xff09;不同&#xff0c;队列遵循“先进先出”&#xf…

EDA - Spring Boot构建基于事件驱动的消息系统

文章目录 概述事件驱动架构的基本概念工程结构Code创建事件和事件处理器创建事件总线创建消息通道和发送逻辑创建事件处理器消息持久化创建消息发送事件配置 Spring Boot 启动类测试消息消费运行项目 概述 在微服务架构和大规模分布式系统中&#xff0c;事件驱动架构&#xff…

仿iOS日历、飞书日历、Google日历的日模式

仿iOS日历、飞书日历、Google日历的日模式&#xff0c;24H内事件可自由上下拖动、自由拉伸。 以下是效果图&#xff1a; 具体实现比较简单&#xff0c;代码如下&#xff1a; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color;…

软考高级架构 - 10.5 软件架构演化评估方法

10.4 软件架构演化原则总结 本节提出了18条架构演化的核心原则&#xff0c;并为每条原则设计了简单而有效的度量方法&#xff0c;用于从系统整体层面提供实用信息&#xff0c;帮助评估和指导架构演化。 演化成本控制&#xff1a;成本小于重新开发成本&#xff0c;经济高效。进…

DocFlow票据AI自动化处理工具:出色的文档解析+抽取能力,提升企业文档数字化管理效能

目录 财务应付 金融信贷业务 近期&#xff0c;DocFlow票据自动化产品正式上线。DocFlow是一款票据AI自动化处理工具&#xff0c;支持不同版式单据智能分类扩展&#xff0c;可选功能插件配置流程&#xff0c;满足多样业务场景。 随着全球化与信息化进程&#xff0c;企业的文件…

C# 探险之旅:第二节 - 定义变量与变量赋值

欢迎再次踏上我们的C#学习之旅。今天&#xff0c;我们要聊一个超级重要又好玩的话题——定义变量与变量赋值。想象一下&#xff0c;你正站在一个魔法森林里&#xff0c;手里拿着一本空白的魔法书&#xff08;其实就是你的代码编辑器&#xff09;&#xff0c;准备记录下各种神奇…

有道云笔记批量导出

前言 最近使用有道云笔记遇到打开过慢&#xff0c;导致笔记丢失&#xff0c;需要会员才能找回之前笔记问题。 决定改用思源&#xff0c;程序中的格式比较难于通过复制保留&#xff0c;即使导出成word 或者pdf&#xff0c;需要一个专门工具导出成Markdown格式&#xff0c;批量…

离线无网环境中基于OpenEuler的everything ISO安装软件

文章目录 1.创建挂载点 2.挂载 ISO 文件: 3.配置 YUM 源 4.清理 YUM 缓存并生成新的缓存: 5.使用 YUM 安装软件包 要在 OpenEuler 系统中挂载ISO &#xff08;下载地址&#xff1a;https://repo.openeuler.openatom.cn/openEuler-20.03-LTS/ISO/x86_64/&#xff09;并使用…

2024最新树莓派4b安装ubuntu20.04.5-server版本全流程解决方案:从烧录到配置桌面到联网!!!

准备工作 硬件工具 树莓派4b&#xff0c;32GSD卡&#xff0c;读卡器 软件工具 ubuntu20.04.5镜像&#xff0c;SD卡格式化工具&#xff0c;烧录软件&#xff0c;远程连接工具。 下面是我通过百度网盘分享的文件&#xff1a;树莓派4bubuntu20.04链接&#xff1a;https://pan…

STM32 OLED屏幕驱动详解

一、介绍 OLED是有机发光二极管&#xff0c;又称为有机电激光显示&#xff08;Organic Electroluminescence Display&#xff0c; OLED&#xff09;。OLED由于同时具备自发光&#xff0c;不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广…

商业银行基于容器云的分布式数据库架构设计与创新实践

导读 本文介绍了某商业银行基于 TiDB 和 Kubernetes(简称 K8s) 构建的云化分布式数据库平台&#xff0c;重点解决了传统私有部署模式下的高成本、低资源利用率及运维复杂等问题。 通过引入 TiDB Operator 自动化管理与容器化技术&#xff0c;银行能够实现多个业务系统的高可用…

项目组件框架介绍[etcd]

文章目录 前言etcd安装Ubuntu 上通过包管理器安装通过源码安装配置 客户端开发包开发包的安装接口介绍添加一个键值对获取一个键值对租约保活机制监听 封装服务注册与发现服务注册服务发现 前言 Etcd 是一个 golang 编写的分布式、高可用的一致性键值存储系统&#xff0c;用于配…

网页爬虫技术全解析:从基础到实战

引言 在当今信息爆炸的时代&#xff0c;互联网上的数据量每天都在以惊人的速度增长。网页爬虫&#xff08;Web Scraping&#xff09;&#xff0c;作为数据采集的重要手段之一&#xff0c;已经成为数据科学家、研究人员和开发者不可或缺的工具。本文将全面解析网页爬虫技术&…

Jmeter如何对UDP协议进行测试?

Jmeter如何对UDP协议进行测试&#xff1f; 1 jmeter-plugins安装2 UDP-Protocol Support安装3 UDP协议测试 1 jmeter-plugins安装 jmeter-plugins是Jmeter的插件管理器&#xff1b;可以组织和管理Jmeter的所有插件&#xff1b;直接进入到如下页面&#xff0c;选择如图的选项进…

计算机网络之网络层超详细讲解

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 计算机网络之网络层超详细讲解 收录于专栏【计算机网络】 本专栏旨在分享学习计算机网络的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; …