TCP

TCP

查看文件大小:字节大小

import os

size = os.path.getsize('0909.py')

print(size)

一、简单的双向通信

  1. server

    import socket
    soc = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    soc.bind(('127.0.0.1',8080))
    soc.listen(5)
    conn,addr = soc.accept()
    data = conn.recv(1024)
    print('客户端发送过来的:',data)
    data = data.upper()
    conn.send(data)
    conn.close()
    soc.close()
    
  2. client

    import socket
    # 192.168.11.152
    # 192.168.11.126
    # 127.0.0.1
    soc = socket.socket()
    soc.connect(('192.168.11.152',8080))
    soc.send('我'.encode())
    data = soc.recv(1024)
    print(data)
    soc.close()
    

二、通信循环

  1. server
import socket

soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

soc.bind(('127.0.0.1', 8080))

soc.listen(5)

conn, addr = soc.accept()

while True:
    data = conn.recv(1024)
    print(data.decode())

conn.close()
soc.close()

  1. client
import socket
soc = socket.socket()
soc.connect(('127.0.0.1',8080))
while True:
    in_s = input('请输入要法送的数据:')
    soc.send(in_s.encode())

2.1实现俩个人之间的通信

  1. server
import socket

soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.bind(('192.168.11.44',8080))  #192.168.11.44
soc.listen(5)
print('等待连接')
conn, addr = soc.accept()
print('客户连接',addr)
for i in range(100):
    data = conn.recv(1024)
    data = data.decode()
    print('客户端发送过来的:', data)
    data1 = input('请输入:')
    conn.send(data1.encode())
conn.close()
soc.close()

  1. client
import socket
soc = socket.socket()
soc.connect(('192.168.11.44',8080))
for i in range(100):
    data1 = input('请输入:')
    soc.send(data1.encode())
    data = soc.recv(1024)
    print('服务端回复的:', data.decode())
soc.close()

三、套接字连接循环

  1. server

    import socket
    #生成一个socket对象
    soc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    #绑定地址跟端口号
    soc.bind(('127.0.0.1',8001))
    #监听(半连接池的大小),不是连接数
    soc.listen(3)
    #等着客户端来连接,conn相当于连接通道,addr是客户端的地址
    while True:
        print('等待客户端连接')
        conn,addr=soc.accept()    #卡主,如果没有客户端连接,会一直卡在这,当有连接,才继续往下走
        print('有个客户端连接上了',addr)
        while True:
            try:
                #windows如果客户端断开,会报错,加了try
                #linux如果客户端,断开,不会报错,会收到空,
                # 所有当data为空时,也break
                #等待接收,最大收取1024个字节
                data=conn.recv(1024)    #会卡主,当客户端有数据过来,才会执行
                if len(data)==0:  #处理linux客户端断开,
                    # 如果在window下这段代码根本不会执行
                    # (即便是客服端发了空,这个地方也不会走到)
                    break
                print(data)
            except Exception:
    
                break
        # 关闭通道
        conn.close()
    
    
    # 关闭套接字
    soc.close()
    
  2. client

    import socket
    soc = socket.socket()
    soc.connect(('127.0.0.1',8080))
    
    while True:
        in_s = input('请输入要发送的数据:')
        soc.send(in_s.encode())
    
    

四、模拟ssh功能

  1. server

    import socket
    import subprocess
    soc=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    soc.bind(('127.0.0.1',8001))
    soc.listen(3)
    while True:
        print('等待客户端连接')
        conn,addr=soc.accept()
        print('有个客户端连接上了',addr)
        while True:
            try:
                data=conn.recv(1024)
                if len(data)==0:
                    break
                print(data)
                obj = subprocess.Popen(str(data,encoding='utf-8'), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
                #执行正确的结果 b 格式,gbk编码(windows平台)
                msg=obj.stdout.read()
                #把执行的结果通过网络传给c端
                conn.send(msg)
            except Exception:
    
                break
        # 关闭通道
        conn.close()
    
    
    # 关闭套接字
    soc.close()
    
    
  2. client

    import socket
    
    soc=socket.socket()
    
    soc.connect(('127.0.0.1',8001))
    while True:
        in_s=input('请输入要执行的命令:')
        soc.send(in_s.encode('utf-8'))
        data=soc.recv(1024)
        print(str(data,encoding='gbk'))
    
    
    #粘包:tcp会把数据量较小,时间间隔较短的数据,当做同一个包发送
    
    
  3. 补充的subprocess模块

    #ssh 是远程执行命令
    #subprocess 执行系统命令的模块
    import subprocess
    #执行系统dir命令,把执行的正确结果放到管道中
    # obj=subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE)
    obj=subprocess.Popen('tasklistdd',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    #拿到正确结果的管道,读出里面的内容
    ss=obj.stdout.read()
    err=obj.stderr.read()
    print('错误信息',str(err,encoding='gbk'))
    #因为windows用的gbk编码,用gbk解码
    # print(str(ss,encoding='utf-8'))
    print(str(ss,encoding='gbk'))
    
    

socketserver开始多线程

TCP可以开始多线程

  1. server

    #使用socketserver写服务端
    #导入模块
    import socketserver
    
    #自己定义一个类,必须继承BaseRequestHandler
    class MyTcp(socketserver.BaseRequestHandler):
        #必须重写handle方法
        def handle(self):
            try:
                while True :  #通信循环
                    # print(self)
                    #给客户端回消息
                    #conn对象就是request
                    #接收数据
                    print(self.client_address)
                    data=self.request.recv(1024)
                    print(data)
                    if len(data)==0:
                        return
                    #发送数据
                    self.request.send(data.upper())
            except Exception:
                pass
    
    
    if __name__ == '__main__':
        #实例化得到一个tcp连接的对象,Threading意思是说,只要来了请求,它自动的开线程来处理连接跟交互数据
        #第一个参数是绑定的地址,第二个参数传一个类
        server=socketserver.ThreadingTCPServer(('127.0.0.1',8009),MyTcp)
        #一直在监听
        #这么理解:只要来一个请求,就起一个线程(造一个人,做交互)
        server.serve_forever()
    
    
    
  2. client1

    import socket
    soc = socket.socket()
    soc.connect(('127.0.0.1',8009))
    while True:
        soc.send('xxx'.encode('utf8'))
        print(soc.recv(1024))
    
    
    
  3. client2

    import socket
    soc = socket.socket()
    soc.connect(('127.0.0.1',8009))
    while True:
        soc.send('xxx'.encode('utf8'))
        print(soc.recv(1024))
    
    
    
posted @ 2019-09-10 21:15  豆瓣酱瓣豆  阅读(109)  评论(0编辑  收藏  举报