首先放出一个 TCP/IP 的程序,这里是单线程服务器与客户端,在多线程一节会放上多线程的TCP/IP服务程序。
这里将服务端和客户端放到同一个程序当中,方便对比服务端与客户端的不同。
TCP/IP是因特网的通信协议,其参考OSI模型,也采用了分层的方式,对每一层制定了相应的标准。
网际协议(IP)是为全世界通过互联网连接的计算机赋予统一地址系统的机制,它使得数据包能够从互联网的一端发送至另一端,如 130207244244,为了便于记忆,常用主机名代替IP地址,例如 baiducom。
UDP (User Datagram Protocol,用户数据报协议) 解决了上述第一个问题,通过端口号来实现了多路复用(用不同的端口区分不同的应用程序)但是使用UDP协议的网络程序需要自己处理丢包、重包和包的乱序问题。
TCP (Transmission Control Protocol,传输控制协议) 解决了上述两个问题,同样使用端口号实现了复用。
TCP 实现可靠连接的方法:
socket通信模型及 TCP 通信过程如下两张图。
[上传失败(image-6d947d-1610703914730)]
[上传失败(image-30b472-1610703914730)]
socketgetaddrinfo(host, port, family, socktype, proto, flags)
返回: [(family, socktype, proto, cannonname, sockaddr), ] 由元组组成的列表。
family:表示socket使用的协议簇, AF_UNIX : 1, AF_INET: 2, AF_INET6 : 10。 0 表示不指定。
socktype: socket 的类型, SOCK_STREAM : 1, SOCK_DGRAM : 2, SOCK_RAW : 3
proto: 协议, 套接字所用的协议,如果不指定, 则为 0。 IPPROTO_TCP : 6, IPPRTOTO_UDP : 17
flags:标记,限制返回内容。 AI_ADDRCONFIG 把计算机无法连接的所有地址都过滤掉(如果一个机构既有IPv4,又有IPv6,而主机只有IPv4,则会把 IPv6过滤掉)
AI _V4MAPPED, 如果本机只有IPv6,服务却只有IPv4,这个标记会将 IPv4地址重新编码为可实际使用的IPv6地址。
AI_CANONNAME,返回规范主机名:cannonname。
getaddrinfo(None, 'smtp', 0, socketSOCK_STREAM, 0, socketAP_PASSIVE)
getaddrinfo('ftpkernelorg', 'ftp', 0, 'socketSOCK_STREAM, 0, socketAI_ADDRCONFIG | socketAI_V4MAPPED)
利用已经通信的套接字名提供给getaddrinfo
mysock = server_sockaccept()
addr, port = mysockgetpeername()
getaddrinfo(addr, port, mysockfamily, mysocktype, mysockproto, socketAI_CANONNAME)
TCP 数据发送模式:
由于 TCP 是发送流式数据,并且会自动分割发送的数据包,而且在 recv 的时候会阻塞进程,直到接收到数据为止,因此会出现死锁现象,及通信双方都在等待接收数据导致无法响应,或者都在发送数据导致缓存区溢出。所以就有了封帧(framing)的问题,即如何分割消息,使得接收方能够识别消息的开始与结束。
关于封帧,需要考虑的问题是, 接收方何时最终停止调用recv才是安全的?整个消息或数据何时才能完整无缺的传达?何时才能将接收到的消息作为一个整体来解析或处理。
适用UDP的场景:
由于TCP每次连接与断开都需要有三次握手,若有大量连接,则会产生大量的开销,在客户端与服务器之间不存在长时间连接的情况下,适用UDP更为合适,尤其是客户端太多的时候。
第二种情况: 当丢包现象发生时,如果应用程序有比简单地重传数据聪明得多的方法的话,那么就不适用TCP了。例如,如果正在进行音频通话,如果有1s的数据由于丢包而丢失了,那么只是简单地不断重新发送这1s的数据直至其成功传达是无济于事的。反之,客户端应该从传达的数据包中任意选择一些组合成一段音频(为了解决这一问题,一个智能的音频协议会用前一段音频的高度压缩版本作为数据包的开始部分,同样将其后继音频压缩,作为数据包的结束部分),然后继续进行后续 *** 作,就好像没有发生丢包一样。如果使用TCP,那么这是不可能的,因为TCP会固执地重传丢失的信息,即使这些信息早已过时无用也不例外。UDP数据报通常是互联网实时多媒体流的基础。
参考资料:
Python可以使用各种网络编程技术,如socket,>
用twisted,用工厂管理连接,每个连接建立transport使用简单方便!参看下面代码:
#Copyright(c)ThePyAMFProject
#SeeLICENSEtxtfordetails
\"\"\"
ExamplesocketserverusingTwisted
@see:U{Documentationforthisexample
raiseSystemExit
fromtwistedinternetprotocolimportProtocol,Factory
fromtwistedinternetimportreactor
fromdatetimeimportdatetime
importpyamf
classTimerProtocol(Protocol):
interval=10#客户端链接到server后,server往客户端发送时间的间隔
encoding=pyamfAMF3
timeout=20#客户端链接到server后多少时间不 *** 作就断开链接的timeout
def__init__(self):
selfstarted=False
#设置编码器
selfencoder=pyamfget_encoder(selfencoding)、
#设置server端将数据编码成amf后存放的缓存地址
selfstream=selfencoderstream
defconnectionLost(self,reason):
ProtocolconnectionLost(self,reason)
print\"locstconnection:
DHCP(Dynamic Host Configuration Protocol,动态主机配置协议),前身是BOOTP协议,是一个局域网的网络协议,使用UDP协议工作,统一使用两个IANA分配的端口:67(服务器端),68(客户端)。主要作用是集中的管理、分配IP地址,使client动态的获得IP地址、Gateway地址、DNS服务器地址等信息。
option字段
DHCP报文中的Options字段可以用来存放普通协议中没有定义的控制信息和参数。如果用户在DHCP服务器端配置了Options字段,DHCP客户端在申请IP地址的时候,会通过服务器端回应的DHCP报文获得Options字段中的配置信息。
获取IP地址过程
实验使用的linux 主机由两个网络接口,其中ens33使用DHCP获取IP地址,ens37使用静态IP地址;因此需要使用ens33来发送数据包。
Change_MACpy用于MAC地址与Bytes类型相互转换。
DHCP_Discoverpy用于发送DHCP Discover报文;其中GET_MACpy见ARP章节。
DHCP_Requestpy用于发送DHCP Request报文。
DHCP_FULLpy用于完成DHCP Client与DHCP Server的报文交互
Wireshark对远程linux主机抓包,结果如下
客户端以广播发送DHCP Discover包,其中报文 *** 作类型为1(请求报文),DHCP客户端的MAC地址设置为00:0c:29:03:a1:08,option53设置报文类型为Discover,option55(请求选项列表)中包含请求的参数。
服务器以单播向客户端回复信息,其中报文 *** 作类型为2(应答报文),分配给客户端的IP为192168160146,option 53设置报文类型为offer,Option 54设置服务器标识为192168160254,其他option为客户端请求列表的应答。
值得注意的是,交互的四个报文中Transaction ID均为0x00000000,表明是同一次DHCP交互报文。
以上就是关于如何在客户端用Python获得服务器重写后的URL全部的内容,包括:如何在客户端用Python获得服务器重写后的URL、如何用python获取websocket数据、Python网络编程 -- TCP/IP等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)