2020/01/13 01-socket基础和TCP编程

馋奶兔 提交于 2020-01-13 23:38:38

基于底层的tcp,udp编程,高层的应用层,http编程
底层的效率高,tcp可以保证数据库安全,效率高

socket(插座),网络编程,是点对点,每一个就是一个孔,中间链接起来,socket简单来讲就是端到端的编程,端对端,建立一个网络通讯的通道,从socket到scoket,从一个插座到另一个插座,建立一个数据通讯的通道
在这里插入图片描述

python也提高了socket.py的模块,是低级的网络编程接口,统一的socket编程接口,所有操作系统通用
在这里插入图片描述
进程间通讯IPC,远程调用RPC,最底层还需要socket开始
在这里插入图片描述
socket掌握TCP有链接协议,UDP无链接协议即可
UDP协议好处是短小,效率高,不保证数据发送出去有没有人收到
在这里插入图片描述
tcp和UDP编程都是端到端

所谓的C/S编程就是server,和client如何通讯
在这里插入图片描述
早期的QQ聊天是需要你选择服务器才可以使用的,只不过现在屏蔽了
在这里插入图片描述
client和server是用功能来分,其实是双向的,数据可以来回,一般把功能强大的,都链接指向的称为server,与它链接的称为client
在这里插入图片描述
TCP的server端比较麻烦,首先需要创建socket对象,
路由管的是IP,到达应用层区分才靠端口。路由到通讯的主机,询问,这个IP上面的对应的端口,比如IP地址对应的TCP 8000是否有进程占用。
资源是分给进程的,所以线程是共享这个资源。

一个应用程序要用网络,必须开一个socket,告诉别人是用上面协议的,地址端口
在这里插入图片描述
默认都指tcp的,所以只要绑定IP和端口即可,一旦某个应用程序绑定了某个协议和端口之后,其他程序不你能再对这个端口占用
绑定只是把端口给你用了,还买开始工作,工作就需要监听端口,listen(),
accepct()允许,会把链接过来的client分配一个新的socket,这样就服务器可以和客户端传输数据了
在这里插入图片描述
recv(),client发来的东西,server 接收
client接受,就需要调用send()方法

在这里插入图片描述在这里插入图片描述在这里插入图片描述
server端,创建socket,做地址端口绑定,监听端口,然就accept。
client通过这个IP地址协议。链接端口,建立链接后。
TCP server 分配一个新的socket,client的读写和这个tcp server的新的socket进行读写操作。
tcp server 端有socket和一个新的socket,这点是比较麻烦的

在这里插入图片描述
socket用完之后,因为会占用文件描述符,用完就可以关闭
在这里插入图片描述
这里其实server端,accept以后会创建一个新的socket出来,客户端的通讯是和这个新的socket进行通讯的,原来的server 的socket是在接收新的客户端链接,
每一个链接其实都要建立一个socket

在这里插入图片描述
每一个链接其实就要一个socket,
在这里插入图片描述

实验

在这里插入图片描述
协议已经写了 AF_INET (ipv4) SOCK_STREAM (tcp)
在这里插入图片描述在这里插入图片描述
windows 和linux都有网络命令,
linux 用 ss -tanl (t=tcp,a=all,n=端口数字 ,l=listen)
windows 用netstat -anp tcp

在这里插入图片描述
用管道找listen的端口
在这里插入图片描述
加断点走到bind结束了在这里插入图片描述
现在还是没有监听端口的,没有监听之前是看不到端口的
在这里插入图片描述
F8继续往下走
在这里插入图片描述
现在就有了
在这里插入图片描述
加上b,是显示哪个进程的
在这里插入图片描述在这里插入图片描述
现在还没退出,到这里,阻塞等待client链接在这里插入图片描述
用这个程序
在这里插入图片描述在这里插入图片描述
链接一下就断掉了
在这里插入图片描述
用的端口是50139

打印的c是打印出了一个元组在这里插入图片描述
l代表local,r代表远端,本地在9999,远程地址在50139在这里插入图片描述
accpet一旦连接成功会生成一个新的socket
在这里插入图片描述
现在读写是要靠新的socket在这里插入图片描述
server一般被动接收数据,使用recv,现在就卡在accept上等待链接在这里插入图片描述在这里插入图片描述
这样就收到数据了,然后就close了
在这里插入图片描述
decode英文意思是 解码,输出是字符串,encode英文原意 编码输出是bytes
socket原始传输的是bytes,否则出错在这里插入图片描述
socket最原始接口得到的是bytes
在这里插入图片描述
**tcp只有三次链接accept之后,创建新的socket,这个新的socket,是被accept的返回值带回来的,是对端的端口,这样就可以和client完成端到端的通讯,
**
在这里插入图片描述
注意:一般recv是在等待数据到来,等待new socket的里面缓冲区有数据
send是发数据,这个new socket可以单独关闭
在这里插入图片描述
同时多个client链接就是高并发,网络IO的高并发
在这里插入图片描述
端口只能绑定一次在这里插入图片描述
接收另一个的链接,下面的s2还可以recv和send在这里插入图片描述在这里插入图片描述
先发送一个
在这里插入图片描述
再创建一个 链接
在这里插入图片描述
现在就两个链接创建了在这里插入图片描述
现在走到35行阻塞在这里插入图片描述
发送也就断开了在这里插入图片描述
之前的发送数据,已经处于假死的状态,socket已经关闭了,但是好处是,再次链接,因为放在缓冲区里,就给你发送出去了在这里插入图片描述
这样就是互相干扰,避免这种阻塞互相干扰,可以利用多线程
在这里插入图片描述
查看监听端口的两种方式在这里插入图片描述

练习写一个群聊程序

在这里插入图片描述
互相能看到发的数据在这里插入图片描述
服务器端应该accept链接,每一个client链接以后要甩出一个new socket进行通信,recv到一个用户的信息,分发给不同的客户端,
停止服务
记录链接的客户端

在这里插入图片描述

写代码就是封装函数和类,先设计类ChatServer,start启动服务,accept接收链接,recv接收数据,stop停止服务
在这里插入图片描述
0.0.0.0代表本地所有IP地址,127.0.0.1自身
在这里插入图片描述
可以用logging打印一下

在这里插入图片描述在这里插入图片描述
现在可以使用,只要创建实例,start之后到accept卡住在这里插入图片描述
在这里插入图片描述
现在一个线程用起来还可以
在这里插入图片描述

tcp是知道对端的,laddr,raddr,socket里面都有这些信息在这里插入图片描述
这样就可以重复发数据了在这里插入图片描述
但是创建另外的链接就没有回来的数据,只有发送的数据在这里插入图片描述
每一次链接的时候都需要一个accept等待,才能链接上来在这里插入图片描述
我们现在这么写的是不可以的
在这里插入图片描述
accept返回之后还要再new一个出来,但是现在的self。recv会进入下面的死循环,轮不到上面语句执行
在这里插入图片描述
多线程试试
在这里插入图片描述
这样就可以了
在这里插入图片描述
现在有两个客户端链接就是两个线程,还有一个主线程,总共三个线程在这里插入图片描述
这一句会导致主线程阻塞在这里插入图片描述在这里插入图片描述
主线程不阻塞了,一执行就直接关闭了在这里插入图片描述在这里插入图片描述
现在可以观察线程的工作方式
在这里插入图片描述
运行,现在就一个accept在跑在这里插入图片描述
链接发送消息在这里插入图片描述
敲回车,就有新的线程了在这里插入图片描述
再次链接发送消息
在这里插入图片描述
现在就有两个线程了
在这里插入图片描述
主动断开现在会产生一个异常出来,把r-x线程崩溃,跟主线程无关
在这里插入图片描述
少了一个r-1在这里插入图片描述
主线程往往是用来管理的,工作线程是用来工作与通讯的

到此为止,点对点的网络通讯 程序就完成了
在这里插入图片描述在这里插入图片描述

面试写一个socket通讯,至少写成这样,多线程有,面向对象也有

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!