【python】socket模块
socket
一丶socket最基本的链接
服务端:
#!/usr/bin/env python # -*- coding:utf-8 -*- import socket#导入socket模块 sk=socket.socket()#实例化socket类 sk.bind(('127.0.0.1',9999,))#绑定ip和端口 sk.listen()#进行监听,sk.listen(num),参数num是表示允许接收多少阻塞在这里的链接 while True: conn, address = sk.accept()#接收客户端信息 print(conn,address)#conn和address分别代表连接和客户端的信息
客户端端链接:
#!/usr/bin/env python # -*- coding:utf-8 -*- import socket sk=socket.socket()#实例化对象 sk.connect(("127.0.0.1",9999,))#链接ip和端口 sk.close()#关闭链接 #如果在这里连接了,上面的服务端代码就会打印出conn和address
二丶服务端和客户端进行交互
服务端:
#!/usr/bin/env python # -*- coding:utf-8 -*- import socket#导入socket模块 sk=socket.socket()#实例化socket类 sk.bind(('127.0.0.1',9999,))#绑定ip和端口 sk.listen()#进行监听,sk.listen(num),参数num是表示允许接收多少阻塞在这里的链接 while True: conn, address = sk.accept()#接收客户端信息 conn.sendall(bytes("欢迎致电",encoding='utf-8'))#接收到链接就发送这个字符串给链接的客户端 while True: ret_bytes=conn.recv(1024)#接收客户端发送过来的消息 acces=str(ret_bytes,encoding='utf-8')#把发送过来的字节码转成utf-8编码 conn.sendall(bytes(acces+"滚",encoding='utf-8'))#把字符串转成字节码发给客户端 #注意: #发送的消息一定要是字节码,所以一定要记得要转成字节码(byte),如果是Int类型就先转成str再转成字节码
客户端:
#!/usr/bin/env python # -*- coding:utf-8 -*- import socket sk=socket.socket()#实例化对象 sk.connect(("127.0.0.1",9999,))#链接ip和端口 while True: ret_bytes=sk.recv(1024)#接收服务端发过来的消息 print(str(ret_bytes,encoding='utf-8'))#把byte字节码转成字符串 inp=input("请输入内容:")#等待客户输入内容 sk.sendall(bytes(inp,encoding='utf-8'))#把用户输入的内容发送到服务端 sk.close()#关闭链接
三丶上传文件
服务端:
#!/usr/bin/env python # -*- coding:utf-8 -*- import socket sk=socket.socket() sk.bind(("127.0.0.1",9998,))#绑定ip和端口 sk.listen()#进行监听,sk.listen(num),参数num是表示允许接收多少阻塞在这里的链接 while True: conn,address=sk.accept()#接收客户端信息 conn.sendall(bytes("欢迎上传",encoding="utf-8"))#接收到链接就发送这个字符串给链接的客户端 byes_ret=conn.recv(1024)#接收客户端发过来的文件大小,用于跳出文件写入的循环 filesize=str(byes_ret,encoding="utf-8")#把字节码转码,转码成字符串 conn.sendall(bytes("ok",encoding="utf-8"))#收到文件大小号回复给客户端叫它发文件,这一步是为了解决粘包问题 filehandle = open("new.jpg", "wb")#先创建一个文件 filepro=0#这个变量是用于储存已经传了多少字节的内容 while True: if filesize==filepro:#如果已传文件长度等于总长度就跳出这个循环 break data=conn.recv(1024)#接收传过来的文件内容 filehandle.write(data)#将内如写入文件 filepro=filepro+len(data)#然后更新已经上传的长度 #下面说明一下粘包问题 #拿上面的发送文件说明一下 #在发送文件大小过去服务端的时候就马上执行发送文件内容,此时文件大小还存在内存中,读取文件的内容又加入到内存中 #此时内存的内容全都发送过去服务端,写入文件,此时就会造成文件错误 #所以我们加了接收“conn.sendall(bytes(‘ok’,encoding=‘utf-8’))”这一步,为了是阻断马上执行下面的代码
客户端:
#!/usr/bin/env python # -*- coding:utf-8 -*- import socket import os sk=socket.socket() sk.connect(("127.0.0.1",9998,))#连接ip和端口 print(str(sk.recv(1024),encoding="utf-8"))#接收“欢迎上传”这个字符串 fsize=os.stat("ok7lht-ruv.jpg").st_size#获取要上传的文件的大小 sk.sendall(bytes(str(fsize),encoding="utf-8"))#将文件大小发送出去 re=sk.recv(1024)#接收返回“ok”的信息,这一步是为了解决粘包的问题 print(str(re,encoding="utf-8"))#打印出接收ok的信息 with open("ok7lht-ruv.jpg","rb") as f:#打开要读取的文件 for line in f: #一行一行来读取文件 sk.sendall(line)#将读取的内容发送给服务端 sk.close()#关闭连接 #下面说明一下粘包问题 #拿上面的发送文件说明一下 #在发送文件大小过去服务端的时候就马上执行发送文件内容,此时文件大小还存在内存中,读取文件的内容又加入到内存中 #此时内存的内容全都发送过去服务端,写入文件,此时就会造成文件错误 #所以我们加了接收“re=sk.recv(1024)#接收返回‘ok’的信息”这一步,为了是阻断马上执行下面的代码
四丶实现并发操作(主要用到的是select模块)
服务端:
#!/usr/bin/env python # -*- coding:utf-8 -*- import select import socket sk1=socket.socket() sk1.bind(("127.0.0.1",8001,)) sk1.listen() sk2=socket.socket() sk2.bind(("127.0.0.1",8002,)) sk2.listen() sk3=socket.socket() sk3.bind(("127.0.0.1",8003,)) sk3.listen() sklist=[sk1,sk2,sk3,] while True: r_list, w_list, e_list = select.select(sklist, [], [], 1)#select模块主要是就监听socket对象哪个发生了变化。发生了变化就会传给r_list for i in r_list: #循环发生变化的对象,然后接受变化对象的链接,从而实现并发连接 conn,address=i.accept() index=sklist.index(i) conn.send(bytes("hellow word "+str(index),encoding="utf-8"))#发送消息给连接socket对象的客户端

浙公网安备 33010602011771号