python的socket的tcp_Python中Socket编程(TCP、UDP)

1. TCP协议下的如何解决粘包问题

TCP(transport control protocol 传输控制协议)  使用Nagle算法,将多次间隔较小且数据量小的数据,合并成大的数据块;接受端无法识别每条数据的边界,因此产生粘包现象。

"""Server"""from socket import *back_log= 5bufsize= 1024ip_port= ('127.0.0.1', 8080)

tcp_server=socket(AF_INET, SOCK_STREAM) # 数据流

tcp_server.bind(ip_port)

tcp_server.listen(back_log)whileTrue:

print('服务端开始处理连接。。。')

conn, addr=tcp_server.accept()

print('客户端连接', conn)

print('客户端地址', addr)whileTrue:try:

data=conn.recv(bufsize)ifnot data:breakprint('接收到的数据', data)

conn.send(data.upper())

except Exceptionase:

print(e)break

"""Client"""

from socket import *bufsize= 1024ip_port= ('127.0.0.1', 8080)

tcp_client=socket(AF_INET, SOCK_STREAM)

tcp_client.connect(ip_port)

tcp_client.send('hello'.encode('utf-8'))

tcp_client.send('world'.encode('utf-8'))

response=tcp_client.recv(bufsize)print('response is ==>', response) #response is ==> b'HELLOWORLD'

解决思路:告知接收端数据长度,导入struct模块,将字节长度封装成4个字节发送给接收方;

服务端 =====》TCP实现远程操作命令

from socket import *

importsubprocess,struct

bufsize= 1024back_log= 5ip_port= ('127.0.0.1', 8080)

tcp_server=socket(AF_INET, SOCK_STREAM)

tcp_server.bind(ip_port)

tcp_server.listen(back_log)whileTrue:

conn, addr=tcp_server.accept()print('current connection', conn)whileTrue:try:

cmd=conn.recv(bufsize)if notcmd:break

print('data from client', cmd)

res= subprocess.Popen(cmd.decode('utf-8'), shell=True,

stderr=subprocess.PIPE,

stdin=subprocess.PIPE,

stdout=subprocess.PIPE)

cmd_res=res.stderr.read()if notcmd_res:

cmd_res=res.stdout.read()print('response is:', cmd_res)

data_length= struct.pack('i', len(cmd_res))

conn.send(data_length)

conn.send(cmd_res)exceptException as e:print(e)break

#conn.close()

客户端 ====》

from socket import *

importstruct

bufsize= 100ip_port= ('127.0.0.1', 8080)

tcp_client=socket(AF_INET, SOCK_STREAM)

tcp_client.connect(ip_port)whileTrue:

cmd= input('>>>>').strip()if notcmd:continue

if cmd == 'quit':breaktcp_client.send(cmd.encode('utf-8'))

length_data= tcp_client.recv(4)

length= struct.unpack('i', length_data)[0]print(length)

response= b''recsize=0while recsize

response+=tcp_client.recv(bufsize)

recsize=len(response)#print('execute result is:', response) # 接受字节长度小于发送数据长度,产生粘包

print('execute result is:', response.decode('gbk'))

tcp_client.close()

2. TCP协议如何实现多个客户端连接(并发处理)

导入socketserver模块,实现ocketserver.BaseRequestHandler,重写 handle 方法

使用

ThreadingTCPServer,线程实现并发

importsocketserverclassMyServer(socketserver.BaseRequestHandler):defhandle(self):print('conn is', self.request) #conn

print('addr is', self.client_address) #addr

whileTrue:try:

data= self.request.recv(1024)if notdata:breakself.request.sendall(data.upper())exceptException as e:print(e)break

if __name__ == '__main__':

ip_port= ('127.0.0.1', 8080)

s=socketserver.ThreadingTCPServer(ip_port, MyServer)

s.serve_forever()

3. 基于UDP套接字

UDP 与TCP 不同,使用socket时用的时 SOCK_DGRAM 数据报

sendto()发送的是元组数据类型,包含数据以及连接

recvfrom()接收的也是数据以及连接

服务端 ====》

from socket import *ip_port= ('127.0.0.1', 8080)

buf_size= 1024udp_server= socket(AF_INET, SOCK_DGRAM) #datagram 数据报

udp_server.bind(ip_port)whileTrue:

data, addr=udp_server.recvfrom(buf_size)print(data)

udp_server.sendto(data.upper(), addr)

客户端====》

from socket import *ip_port= ('127.0.0.1', 8080)

buf_size= 1024udp_client= socket(AF_INET, SOCK_DGRAM) #datagram 数据报

whileTrue:

msg= input('==>:').strip()

udp_client.sendto(msg.encode('utf-8'), ip_port)

response, addr=udp_client.recvfrom(buf_size)print(response.decode('utf-8'))

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值