赞
踩
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("192.168.1.103", 8888))
while True:
data, addr = s.recvfrom(1024)
print("%s : %s" % (str(addr), data.decode("gbk")))
msg = input("客服请输入:")
s.sendto(msg.encode("utf-8"), addr)
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
while True:
msg = input("用户说话:")
addr = ("192.168.1.103", 8080)
s.sendto(msg.encode("utf-8"), addr)
data = s.recvfrom(1024)
print("%s : %s" % (str(data[1]), data[0].decode("gbk")))
SOCK_STREAM(流式套接字,主要⽤于TCP协议)或者 SOCK_DGRAM(数据报套接字,主要⽤于UDP协议)
绑定端口和TCP一样,但是不需要调用listen()方法,而是直接接收来自任何客户端的数据。
UDP是没有连接的,所以不需要三次握手,也就不需要调用listen和connect。
因为没有连接状态,每次通信的时候,udp都调用sendto和recvfrom,可以传入IP地址和端口。
data表示接受到的传来的数据,是bytes类型,
data.encode(“utf-8”)编码,将字符串类型转换为bytes类型。
data.decode(“gbk”)解码,将bytes类型转换为字符串类型。 以发送方的编码格式为准
import socket def main(): server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(("192.168.1.103", 8888)) server_socket.listen(11) # 半连接池 在服务端会有一个队列,这里代表服务端最高只能接受11个请求数(并不是连接数) while True: print("等待新用户链接.....") client_socket, addr = server_socket.accept() print("%s 已成功连接" % str(addr)) while True: data = client_socket.recv(1024) if not data: # 如果为空 就是客户断开链接 结束对话 print("%s 已断开链接 结束对话" % str(addr)) break print("%s : %s" % (str(addr), data.decode("gbk"))) msg = input("客服请输入:") client_socket.send(msg.encode("utf-8")) if __name__ == "__main__": main()
import socket def main(): client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ip = input("请输入目标IP:") port = int(input("请输入目标端口:")) addr = (ip, port) # 链接服务器,进行tcp三次握手 client_socket.connect(addr) while True: msg = input("用户输入:") client_socket.send(msg.encode("utf-8")) # 接收对方发送过来的数据,最大接收1024个字节 data = client_socket.recv(1024) print("%s : %s" % (str(addr), data.decode("gbk"))) client_socket.close() if __name__ == "__main__": main()
tcp面向连接(确认有创建三次握手,连接已创建才作操作),udp面向数据报
通信双⽅必须先建⽴连接才能进⾏数据的传输,双⽅都必须为该连接分配必 要的系统内核资源,以管理连接的状态和连接上的传输。双⽅间的数据传输都可以通过这⼀个连接进⾏。完成数据交换后,双⽅必须断开此连接,以释放系统资源。这种连接是⼀对⼀的,因此TCP不适⽤于⼴播的应⽤程序,基于⼴播的应⽤ 程序请使⽤UDP协议。
超时重传
发送端发出⼀个报⽂段之后就启动定时器,如果在定时时间内没有收到应答 就重新发送这个报⽂段。
TCP为了保证不发⽣丢包,就给每个包⼀个序号,同时序号也保证了传送到 接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回⼀个相 应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确 认,那么对应的数据包就被假设为已丢失将会被进⾏重传。
错误校验
TCP⽤⼀个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。
流量控制和阻塞管理
流量控制⽤来避免主机发送得过快⽽使接收⽅来不及完全收下
使⽤socket创建的套接字默认的属性是主动的,使⽤listen将其变为被动的,这样就可以接
客户端
import socket def main(): client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ip = input("请输入目标服务器IP:") port = int(input("请输入目标服务器端口:")) addr = (ip, port) client_socket.connect(addr) file_name = input("请输入文件名:") client_socket.send(file_name.encode("utf-8")) data = client_socket.recv(1024*1024) while data: with open("new" + file_name, "wb") as f: f.write(data) client_socket.close() if __name__ == "__main__": main()
服务器
import socket def get_content(file_name): try: with open(file_name, "rb") as f: content = f.read() return content except: print("没有下载的文件%s" % file_name) def main(): server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(("192.168.1.103", 8888)) server_socket.listen(11) while True: client_socket, addr = server_socket.accept() print("%s 已成功连接准备下载文件....") data = client_socket.recv(1024) file_name = data.decode("utf-8") print("要下载的文件名是 %s" % file_name) file_content = get_content(file_name) # 因为是rb读取的 read(xxx, "rb")操作返回的是bytes 所以无需编码 if file_content: client_socket.send(file_content) client_socket.close() if __name__ == "__main__": main()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。