2020/01/13 03-socket常用方法和makefile使用(面试会考)

在这里插入图片描述
之前写的群聊程序,要变成真正能够使用的,就需要考虑锁的问题,对同一数据结构,有的在写,有的在读,刚才的代码多线程使用同一字典,别的线程在遍历,其他可能要加一个,遇到这个时候,只能加锁

在tcp server模型中,其实不止一个socket,一个socket做listen,同时listen之后就需要accept,用来等待链接,当链接过来之后,会把这个真正的链接交给new socket来处理,创建的这个新的socket 来跟客户端建立链接,也就是每建立链接会多出一个socket(在server上看)

原始的accept,recv,send(一般不阻塞,因为输出的缓冲很难填满)方法全是阻塞的,多个用户使用就需要使用多线程,多线程里进程资源共享,但是多线程运行就涉及到锁,加锁的原则还是尽可能短的加锁

这三个地方就可以分别开一个线程出来
在这里插入图片描述
多线程和socket结合在一起,有可能面试要求你手写,让你写tcp的socket客户端
在这里插入图片描述在这里插入图片描述在这里插入图片描述

socket常用方法

在这里插入图片描述
recv要求必须给一个bufsize,默认是阻塞的工作方式
在这里插入图片描述
recvfrom,可以顺便把对端的socket信息发送回来,会告诉你这个信息来自于谁,两端的地址都在数据包里,返回一个二元组(bytes,address),但是recvfrom一般不用,send的时候知道对端是什么,是有链接协议的
在这里插入图片描述
因为socket通讯时两端,其他的收不到,就不需要recv from在这里插入图片描述
指定一个buffer,想写到哪里去,指定写多少字节,很少使用
在这里插入图片描述
发i返回值里面告诉你从哪里来
在这里插入图片描述
发送数据
在这里插入图片描述
官方解释有可能send会被打断,比如你要发100个字节,但是比较繁忙,会给你发50个字节,使用sendall,就会循环调用send,直到把你指定的数据发送完毕为止
在这里插入图片描述在这里插入图片描述在这里插入图片描述
会调用循环send方法,直到数据发送完毕
在这里插入图片描述
一般情况下用send没什么问题,TCP协议一般是保证数据安全的,繁忙的时候建议sendall,sendall是高级函数,本质上调用send,send本质上调用的是系统调用

有时候会进行判断,发送给数据的时候,对端会做一个验证,看看数据是否发完,这样可以用sendall,保证数据发完

send to,给地址发送数据 ,UDP
在这里插入图片描述
senffile可以指定发送文件,字节流bytes,linux下有senfile机制,是比较高效的机制,可以减少用户空间和内核空间的数据拷贝过程,windows不支持(windows退化程send,一个文件几个字节几个字节的发送,相当于sendall效果)
offset支持偏移量

sendfile就是想要做0拷贝
在这里插入图片描述在这里插入图片描述
getpeername拿到对端的地址
在这里插入图片描述在这里插入图片描述
还有一种方式,拿的是自己sock的本地地址,peername是对端地址
在这里插入图片描述
这几个方式用的比较少,都是对整个工作模式的设定,比如设置阻塞模式还是非阻塞模式的,超时时间,还有一些其他工作方式在这里插入图片描述
不同操作系统对socket实现不相同,所以谁当参数必须要查看对应的操作系统
在这里插入图片描述

重点掌握

在这里插入图片描述在这里插入图片描述

MakeFile

socket也是文件,是一个资源,socket可以转换成一个文件在这里插入图片描述
发送几个数据没看到,是因为缓冲区没满在这里插入图片描述
直接退出是就不阻塞,读出了在这里插入图片描述
缓冲区满了就可以,这样就使用了类文件对象在这里插入图片描述
fileno是取文件描述符,一个文件对象用open打开的话会得到一个文件描述符,socket也可以得到一个文件描述符,这里只不过是把socket封装的操作起来像文件对象一样在这里插入图片描述
本质上是用socket通讯,转换成一个类文件对象

原始的socket在recv和send的时候需要用bytes,封装成类文件对象,有编码就是个字符串对象
read读出来的东西是字符串,现在收到数据也需要回礼,

在这里插入图片描述
不可写
在这里插入图片描述
还需要选择模式,运行一下就报错了,r,w,b是不允许 的
在这里插入图片描述
要这么写,源码里只认rwb这三个字符

在这里插入图片描述
这样就可以了,写rw在这里插入图片描述
改造一下,能够循环起来,读写循环,recv和send,或者read write
在这里插入图片描述在这里插入图片描述
用read方法需要等缓冲区填满,不能读换行符,实际我们发送的已经换行了在这里插入图片描述
使用readline,没看到换行符不理你,敲一个回车
在这里插入图片描述
敲个回车,这样就可以了在这里插入图片描述
可以进一步改造,扔到线程里在这里插入图片描述
t.join扔到一个线程里死循环在这里插入图片描述
现在可以判断收到的信息是quit就退出,strip把换行符去掉在这里插入图片描述
makefile,拿到后不需要socket在这里插入图片描述
makiefile按照道理在所有的socket上都可以使用
之前的程序用makefile改造试试在这里插入图片描述在这里插入图片描述
回车就有消息收到
在这里插入图片描述
发送quit,但是还没断开在这里插入图片描述
这里其实已经把该关 的关了
在这里插入图片描述
如果想要断开也要有个反应,调用socket的close
在这里插入图片描述
这里最好flush,不flush有可能压数据在这里插入图片描述
现在发送quit就断开了 在这里插入图片描述
如果只是把F.CLOSe但是socket还在,所以要把socket也关闭在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述
客户端直接断开,可能这里就会报错,捕获这个异常,直接quit即可在这里插入图片描述在这里插入图片描述在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值