Python中socket与socketserver的简单应用

socket与socketserver的简单应用

tcp&udp

  • socket(不能并发)

基本步骤(服务端)

  1. 实例化socket对象
  2. 绑定IP和端口
  3. 对IP下的端口进行监听
  4. 等待连接
  5. 收发数据
  6. 关闭socket对象
import socket
import os
import time
server = socket.socket()

server.bind(('localhost',6969))#绑定端口
server.listen()#监听,最多挂起等待的链接
print('等电话')
while True:
    conn,adss = server.accept()#等电话进来,f返回示例和地址,相当于电话与接听者的关系
    print(conn,adss)
    print('电话来了')
    while True:
        try:
            data = conn.recv(1024)#接收数据1024字节
        except ConnectionResetError as e:#挂断时会报错
            break
        print(data)
        print(data.__sizeof__())
        # if not data:
        #     break
        #ssh的实现,输入命令,返回服务端的结果
        cmd = os.popen(data.decode()).read()#popen接收str,返回str
        if len(cmd) == 0:
            cmd = 'cmd out of range'
        #发送整体长度
        #连续send会发生粘包问题,buffer缓存区中会将两个数据并和
        conn.send(str(len(cmd.encode())).encode())#中文encode会变长,lens前后会发生变化  cmd
        # time.sleep(0.5) #1.休眠隔断,防止粘包
        client_rec = conn.recv(1024) #2.接收返回数据,进行分割
        conn.send(cmd.encode('utf-8'))#发送全部数据,进入buffer缓存区
        #直接返回相同结果
        # conn.send(data.upper())
    print('电话挂了')

server.close()

基本步骤(客户端)

  1. 实例化socket对象
  2. 连接IP和端口号
  3. 收发数据
  4. 关闭socket实例化对象
import socket

#声明socket类型,并生成链接对象
client = socket.socket()

client.connect(('localhost',7000))
while True:
    msg = input('>>输入你要发的信息:').strip()
    # client.send(b'hellow word')
    if not msg:
        continue    #不能发空的,
    client.sendall(msg.encode('utf-8'))#sendall//循环send
    #从缓存区中读出全部数据后,再进行新的指令
    lens = client.recv(1024)  #接收长度,二进制
    lens = int(lens)
    client.send('on ready'.encode('utf-8'))
    # print(lens)
    sum = 0
    while lens >sum:
        #防止粘包,影响后续操作,只接受等大小数据
        if lens-sum > 1024:
            size = 1024
        else:
            size = lens-sum
        data = client.recv(size)
        sum+=int(len(data))
        print(data.decode())
    print(sum)
client.close()
  • socketserver(可并发)

基本步骤(服务端)

  1. 创建一个继承自BaseRequestHandler的类,
  2. 重写handle方法,该方法为具体客户端连接时的执行行为
  3. 调用TCPServer或UDPServer方法
import socketserver

class mySocketServer(socketserver.BaseRequestHandler):
    def setup(self):
        print(111)
    def handle(self):
        print('accept the phone')
        while True:
            try:
                self.data = self.request.recv(1024).strip()
            except ConnectionResetError as e:
                print('turn off phone')
                break
            print('keep online')
            print(self.data)
        # print('发送成功')
            #linux上执行下面
            # if not self.data:
            #     print('turn off phone')
            #     break
            self.request.sendall(self.data.upper())



if __name__ == '__main__':
    host,port = 'localhost',7000
    #多并发
    server = socketserver.ThreadingTCPServer((host,port),mySocketServer)
    server.serve_forever()

基本步骤(客户端)

同socket一样,不用变化

import socket
import hashlib
client = socket.socket()
client.connect(('localhost',7000))

while True:
    msg = input('输入文件路径》》').strip()

    if not msg:
        continue
    client.sendall(msg.encode('utf-8'))
    #获取文件大小
    lens = client.recv(1024)
    lens=  int(lens.decode())
    #防止粘包
    client.send('on ready'.encode('utf-8'))
    if msg.startswith('get'):
        # filename = msg.split()[1]
        filename = 'pytest.py'
        print(lens)
        m = hashlib.md5()
        with open(filename,'wt') as f:
        #全部读取
            sum_size = 0
            while sum_size < lens:
                if lens-sum_size>=1024:
                    size = 1024
                else:
                    size = lens-sum_size
                data = client.recv(size)
                sum_size+=len(data)
                print(data.decode())
                m.update(data)
                f.write(data.decode())
        print(sum_size)
        server_md5 = client.recv(1024).decode()
        file_md5 = m.hexdigest()

client.close()
  • udp发送与接收

客户端

import socket

sk = socket.socket(type=socket.SOCK_DGRAM)

server = ('localhost',9001)
sk.sendto(b'11111',server)

服务端

import socket

sk = socket.socket(type=socket.SOCK_DGRAM)
sk.bind(('localhost',9001))
#不用在建立请求
msg,address = sk.recvfrom(1024)
print(msg,address )
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值