标签:抽象 绑定 encode ddr send 双向 bsp 消息 www.
Socket:套接字
一、Socket是在应用层与TCP\IP协议族通信的中间软件抽象层,它把传输层与网络层复杂的操作抽象为几个简单的接口共应用层调用已实现进程在网络中的通信。
二、套接字:源IP地址和源端口号以及目标IP地址和目的端口号的组合称为套接字。是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的两方的一种约定,用套接字中的相关函数来完成通信过程。
有人将socket说成是ip+port(端口号),ip标识网络中的主机,port标识主机上的应用程序
二、Socket分为两种:基于文件型的(AF_UNIX)、基于网络型的(AF_INET)
基于网络型(AF_INET)又分为两种:tcp、udp(不需要手动建立连接)
三、Socket基于网络型的TCP协议工作流程图:
先从服务端说起:
1.先初始化:socket>>>>>>>>>soc=socket.socket() 调用模块中的类产生套接字对象,
可以添加参数(三个参数:家族、类型,0),默认为基于网络型的
2.与端口绑定:bind(元组) 参数为(ip,端口)
3.对端口进行监听:listen()
4.调用阻塞,等待客户端连接: accept() 如果客户通过connect成功连接就执行,并且 返回两个值:1.一个新的套接字
2.客户端的地址(ip和服务器相同,端口号不同,元组的形式)
5.用新的套接字进行操作数据:1.recv(1024) 参数1024表示每次从缓冲区读取的数据 的长度
2.send(‘要发送的数据’.encode(编码方式))
客户端:
初始化客户端:socket.socket()
连接服务器:connect()
如果连接成功,此时客户端就可以发送数据,服务端就可以接受请求并处理请求,然后 把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
四、socket模块中的socket类的初始化参数:
参数控制选择家族、模式等,默认为基于网络型的、TCP(需要建立连接)的套接字
第一个参数:选择是基于网络型,还是基于文件型
第二个参数:选择TCP模式(需要手动建立连接),还是UDP模式(不需要建立连接)
第三个参数:通常默认为0
五、套接字(是个对象,如下面的s)的常用方法:
解析关键:
1、client,addr=accept()用于接收客户端的连接请求,且会阻塞。当客户端出现connect并且地址一致时,连接成功并且执行后面的代码。
返回值1表示生成一个新的套接字:并且必须用这个新的套接字去操作数据
返回值2客户端的地址(包括客户端ip与端口号,注意同一台计算机上服务器与客户 端的ip是相同的)
2、recv是从操作系统的缓冲区中读取数据的,并且会阻塞,只有向另一端发送数据,recv 操作系统的从缓冲区读到内容,下面的代码才会被执行。
总结:
一、默认情况下:使用的是基于网络的,且协议为TCP:
TCP是基于连接的,所以必须先启动服务端再启动客户端,否则报错。
且一次连接之后只能跟一个客户端通信,别的服务端想实现通信必须先让服务端与原客户端断开连接,这就用到了,循环的去接收连接。
循环接收客户端连接
循环收发数据(看上面recv介绍的循环结束条件)
当存在循环发送、接受数据时,结束条件就是客户端强行关闭,
客户端强行关闭有两种情况:
1.在linux系统中客户端强行关闭,recv会接收到空消息。不会导致服务端报错,所以判断recv的值是否为空为结束条件。
2.而window下,客户端强行关闭,recv不会接受空消息,而是直接报错。所以需要捕捉异常。并且以捕捉到异常作为结束条件。(即放在except后break)
二、基于网络的,UDP协议:(需要指明参数)
UDP套接字是无连接的,所以先启用哪一端,都不会报错。
由于UDP是无连接的,所以可以同时多个客户端与服务端同时通信。
不需要手动建立连接:
服务端指定参数后,只需要绑定(bind)ip地址与端口号不需要监听和接收连接请求
客户端也需要指定参数,不需要connect手动连接,可直接操作数据。多个客户端可 以共存,同时向服务端发送数据。注意客户端发送数据时,要指明(ip,端口号),即 sendto(),参数出了要发送的数据,还要接上服务器的ip地址和端口号。
标签:抽象 绑定 encode ddr send 双向 bsp 消息 www.
原文地址:https://www.cnblogs.com/yu-931017/p/10178901.html