网络编程——Tcp套接字

news/2024/11/29 17:23:58/

在这里插入图片描述

文章目录

  • 1. 简单的TCP网络程序
    • 1.1 设置监听
    • 1.2 服务器提供连接
    • 1.3 服务器提供服务
    • 1.4 客户端进行连接
    • 1.5 本地测试
    • 1.6 改进版本
    • 1.7 再次测试

1. 简单的TCP网络程序

TCP和UDP差不多,我们还是初始化和启动:
在这里插入图片描述
因为客户端和服务器是会有共同的头文件,所以可以放在同一文件中:
在这里插入图片描述
既然需要网络通信,我们一定要创建套接字。
在这里插入图片描述
因为TCP是面向字节流的,所以使用SOCK_STREAM。这里用的是PF_INET,它和AF_INET是一样的。

套接字创建完成后,我们就可以bind了。
在这里插入图片描述
这里ip的意思是如果ip为空,就用这个宏把所有ip都绑上,如有指定ip,就把字符串转成无符号整数类型。
这个inet_aton函数也是将字符串类型转成无符号整数。
在这里插入图片描述
然后把这个填好的信息写入内核:
在这里插入图片描述

1.1 设置监听

为何要监听呢
udp是无连接的,tcp是面向连接的。如果想让客户端连接服务器,那么服务器首先要有连接来等待客户端。
在这里插入图片描述
这个函数的作用是:将套接字文件描述符从主动转为被动文件描述符,然后用于被动监听客户端的连接。

第二个参数:是一个整数,具体解释后面再说。

在这里插入图片描述
监听完了,就可以让别人连接你服务器了。

1.2 服务器提供连接

我们可以使用这个函数来连接:
在这里插入图片描述
这里第二个参数是输出型参数,第三个参数是输入输出型参数。让知道是哪个客户端连接的。

返回值:
成功:成功则返回一个新的fd,专门用于与连接成功的客户端进行通信。
失败:返回-1 ,并设置errno

为什么这里要返回一个新的文件描述符呢
原来的文件描述符的工作是:获取新的连接(前提有客户端来连接),所以也被叫做监听socket。新返回的文件描述符的工作是:为用户提供网络服务的socket,主要进行IO

就如图一个是拉客,一个是服务客人一样。

在这里插入图片描述
那么成员变量这里我们也应该改准确一点。

在这里插入图片描述

1.3 服务器提供服务

我们可以先提供简单的服务,把客户端发送的小写改成大写。
在这里插入图片描述

我们知道:TCP是面向字节流的,那么我们该用什么方式来读和写呢
前面我们在学习文件间通信的时候,用的是read和write,它们就是面向字节流的
在这里插入图片描述
这里s==0的意思是:读到的数据为0,说明对方关闭,client 退出。这里和管道那里的原理是一样的,读端一直在读,写端不写了,并且关闭了写端,读端会读到0,代表对端关闭。
在这里插入图片描述
这里strcasecmp的意思是:忽略大小写。如果客户自己输入退出,或者客户端退出,或者读取错误,三种情况会退出循环,结束服务。
在这里插入图片描述
如果一个进程对应的文件fd,打开了没有被归还,文件描述符泄漏

到这里,我们可以开始转换大小写了。
在这里插入图片描述
这里read和write用的都是同一个文件描述符。因为TCP和UDP支持全双工
在这里插入图片描述
到这里,我们就可以让服务器启动了。

1.4 客户端进行连接

在这里插入图片描述
因为客户端需要连接服务器,所以需要服务器的IP和端口号,所以个数没有3个就打印使用手册。有的话就把服务器的IP和端口号取出来。

客户端需要bind吗
需要,但是不需要自己显示的bind

需要listen(监听)吗和需要accept(获取连接)吗
都不需要

那么创建stocket套接字后,客户端需要做什么呢
向服务器发起链接请求
在这里插入图片描述
返回值
在这里插入图片描述
这里返回值有个隐藏信息:发起请求,connect 会自动帮我们进行bind
在这里插入图片描述
那么发起请求前,我们要填写信息知道我们是往哪里发送请求的。

下面我们就可以客户端去发送消息了:
在这里插入图片描述
定义一个全局的quit。当客户端输入quit后,就退出。
在这里插入图片描述
当客户端把消息写入成功后,我们要读取服务器给我们反馈的消息。
在这里插入图片描述

1.5 本地测试

在这里插入图片描述
这里看到是一个客户端,我们知道一个服务器是可以连多个客户端的,我们测试一下:
在这里插入图片描述
可以看到左边的客户端可以进行服务,右边的客户端没有响应。
在这里插入图片描述
左边客户端退出了,右边的就显示了。这是为什么呢?

在这里插入图片描述
原因:这里是单进程,一旦进入进入transService,主执行流就一直循环执行,只能提供完毕服务之后才能再次进行accept。

1.6 改进版本

我们知道:父进程打开的文件会被子进程继承的
在这里插入图片描述
在子进程中,我们可以把listenSock关闭,防止别人来修改。子进程退出后,父进程一定要把serviceSock关闭,不然父进程能使用的文件描述符会越来越少。

那么现在子进程退出了,父进程需要去等待吗
如果我们使用了waitpid它默认是阻塞等待,那么就会和上面的情况一样。如果我们使用WNOHANG,会比较麻烦,因为我们需要把每个子进程的pid都记录下来。

方法一
在这里插入图片描述
我们可以让父进程去忽略子进程,这样我们父进程就不需要自己释放了。但是只能在Linux上进行。

方法二
在这里插入图片描述
这里在爸爸进程里再次创建子进程,然后就让爸爸进程退出,这样爷爷进程就不会被阻塞,直接等待成功。那么孙子进程就去执行服务,但是它是一个孤儿进程,就会被OS领养,回收问题就交给了系统了。

但是创建多进程的消耗很大,因为需要创建进程的虚拟地址空间和页表。那么我们就可以用多线程的方式。

方法三
在这里插入图片描述
那么我们该给线程传什么样的参数呢?肯定要有客户端IP、客户端端口号、套接字。
在这里插入图片描述
在这里插入图片描述
我们把这个指针传给线程,这样线程就能把所有数据给拿到了。
在这里插入图片描述
但是这个回调函数是在类部,有一个隐藏的this指针。
在这里插入图片描述
但是加上static后,就无法使用类内的其它成员了。
在这里插入图片描述
在这里插入图片描述
在构造的时候把this传进去。
在这里插入图片描述
这样就可以使用了。

1.7 再次测试

在这里插入图片描述


http://www.ppmy.cn/news/703658.html

相关文章

java ++在前和在后 区别

在Java中,操作符可以放在变量前面,也可以放在变量后面,这两种情况有一些区别。 前置递增(i):先进行加1操作,然后再进行其它操作。 例如: int i 1; int a i; // 先将i加1&#…

硬盘的接口,总线,协议知识点总结

在服务器测试中,关于storage的测试是非常多的,我们会接触很多的盘,比如nvme,m.2,SSD等.当然也有不少概念和协议之类的东西,比如:SATA,PCIe,M.2,NVMe…这些名词想必大家也见得多了,总线,协议,接口也听得耳朵…

硬盘接口类型

硬盘接口类型 硬盘接口类型 并行接口 与 串行接口硬盘接口类型 ATA接口协议SCSI接口协议 参考 并行接口 与 串行接口 并行接口:指采用并行传输方式来传输数据的接口标准。 特点:数据的各位同时进行传送,传输速度快,但当传输距离…

【elementplus】解决el-table开启show-overflow-tooltip后,tooltip的显示会被表格边框遮挡的问题

如图所示: 原因: 1. el-table没有设置高度;2.就是被遮住了 解决: 方法一:给el-table设置高度 方法二: .el-table {overflow: visible !important;}如果不想给el-table设置高度,就直接使用方法二解决即可

在excel表格中画斜线

WIN7: 1)点击你要画斜线的单元格按 ctrl1选择边框选项卡勾选斜线。 2)在在单元格里面斜线的两边要换行,用altenter。(如图:) MAC: 1)点击你要画斜线的单元格按 ctrl1选…

excel表格如何画斜线并写字

参考https://jingyan.baidu.com/article/e6c8503c49ac7fe54f1a18af.html 都在’设置单元格格式‘中进行设置 斜线是边框选项卡——有斜线选项 写字是在字体选项卡——斜线两边的文字分别设置上标和下标 ps:设置单元格格式的时候,我的界面没有边框选项,只…

excel单元格斜线_怎么在excel中画斜线?怎么在excel表格中画斜线?

在excel表格中画斜线的技巧教程: 1.在Excel中打开一个空白工作簿。 2.您可以在任何大小的单元格中执行此操作,但是如果先将其增大则更容易理解。为此,我们只需单击并按住第1行和第2行之间的线,然后将其拖动到所需的高度即可。然后…

wps word如何画表格斜线

wps word如何画表格斜线:https://jingyan.baidu.com/article/d8072ac4b17634ec95cefd92.html