网络编程

基于tcp协议的简单通话

server端

import socket
sk =socket.socket()

sk.bind(('127.0.0.1',8080))     #绑定卡(设置ip地址端口号)
sk.listen()                     #监听,等待接收电话
conn,addr = sk.accept()         #建立连接
while True:
ret
=conn.recv(1024).decode('utf-8') if ret == 'bye': break print(ret) info = input('>>>') conn.send(bytes(info.encode('utf-8'))) conn.close() sk.close()

client端

import socket
sk = socket.socket()    #创建一个链接

sk.connect(('127.0.0.1',8080))   #拨打对方号码(对方端口地址)
while True:
    info = input('>>>')
    sk.send(bytes(info.encode('utf-8')))
    ret = sk.recv(1024).decode('utf-8')
    print(ret)
    if ret == 'bye':
        sk.send(b'bye')
        break
  
sk.close()            #关闭

基于udp的简单通话

server端

import socket
sk =socket.socket(type=socket.SOCK_DGRAM)
sk.bind(('127.0.0.1',8080))

while True:
    msg,addr = sk.recvfrom(1024)
    print(addr)
    print(msg.decode('utf-8'))
    info = input('>>>')
    info = ('来自server端的消息:%s'%info).encode('utf-8')
    sk.sendto(info,addr)

sk.close()

 client端1

import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
ip_port = ('127.0.0.1',8080)

while True:
    info = input('小白说:')
    info = ('来自小白的消息:%s'%info).encode('utf-8')
    sk.sendto(info,ip_port)
    msg,addr = sk.recvfrom(1024)
    print(msg.decode('utf-8'))

sk.close()

  client端2

import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
ip_port = ('127.0.0.1',8080)

while True:
    info = input('小黑说:')
    info = ('来自小黑的消息:%s' % info).encode('utf-8')
    sk.sendto(info,ip_port)
    msg,addr = sk.recvfrom(1024)
    print(msg.decode('utf-8'))

sk.close()

 

黏包现象

基于tcp的黏包现象,但不丢包

server端

import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8090))
sk.listen()

conn,addr = sk.accept()
while True:
    info = input('>>>').encode('utf-8')
    conn.send(info)
    ret = conn.recv(1024).decode('utf-8')
    print(ret)

conn.close()
sk.close()

client端

import socket
import subprocess
sk = socket.socket()

sk.connect(('127.0.0.1',8090))
while True:
    cmd = sk.recv(1024).decode('gbk')
    ret = subprocess.Popen(cmd,shell=True,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE)
    std_out = 'stdout:'+(ret.stdout.read()).decode('gbk')
    print(std_out)
    std_err = 'stderr:'+(ret.stderr.read()).decode('gbk')
    print(std_err)
    sk.send(std_out.encode('utf-8'))
    sk.send(std_err.encode('utf-8'))
sk.close()

基于udp远程下发命令,不黏包,丢包不可靠

server端

import socket
sk = socket.socket(type=socket.SOCK_DGRAM)
sk.bind(('127.0.0.1',8090))
msg,addr = sk.recvfrom(1024)

while True:

    cmd = input('>>>')
    if cmd =='q':
        break
    sk.sendto(cmd.encode('utf-8'),addr)
    msg,addr = sk.recvfrom(1024)
    print(msg.decode('utf-8'))
sk.close()

client端

import socket
import subprocess
sk = socket.socket(type=socket.SOCK_DGRAM)
addr = ('127.0.0.1',8090)
sk.sendto('吃了么'.encode('utf-8'),addr)
while True:
    cmd,addr = sk.recvfrom(1024)
    ret = subprocess.Popen(cmd.decode('gbk'),shell=True,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
    std_out = 'stdout:'+(ret.stdout.read()).decode('gbk')
    print(std_out)
    std_err = 'stderr:'+(ret.stderr.read()).decode('gbk')
    print(std_err)
    sk.sendto(std_out.encode('utf-8'),addr)
    sk.sendto(std_err.encode('utf-8'),addr)

sk.close()

解决黏包问题(方法一):

server端

import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8090))
sk.listen()

conn,addr = sk.accept()
while True:
    cmd = input('>>>')
    if cmd == 'q':
        conn.send(b'q')
    conn.send(cmd.encode('gbk'))
    num = conn.recv(1024).decode('utf-8')
    conn.send(b'ok')
    ret = conn.recv(int(num)).decode('gbk')
    print(ret)

conn.close()
sk.close()

client端

import socket
import subprocess
sk = socket.socket()

sk.connect(('127.0.0.1',8090))
while True:
    cmd = sk.recv(1024).decode('gbk')
    if cmd == 'q':
        break
    ret = subprocess.Popen(cmd,shell=True,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE)
    std_out =ret.stdout.read()
    std_err =ret.stderr.read()
    sk.send(str(len(std_out)+len(std_err)).encode('utf-8'))
    sk.recv(1024)    #ok
    sk.send(std_out)
    sk.send(std_err)
sk.close()

#好处:确定到底接收多大的数据
#不好的地方:多了一次交互

解决黏包问题(方法二):

引用struct模块

server端

import socket
import struct
sk = socket.socket()
sk.bind(('127.0.0.1',8090))
sk.listen()

conn,addr = sk.accept()
while True:
    cmd = input('>>>')
    if cmd == 'q':
        conn.send(b'q')
    conn.send(cmd.encode('gbk'))
    num = conn.recv(4)             #收到要发的数据的长度
    num = struct.unpack('i',num)[0]

    ret = conn.recv(int(num)).decode('gbk')
    print(ret)

conn.close()
sk.close()

client端

import socket
import subprocess
import struct
sk = socket.socket()

sk.connect(('127.0.0.1',8090))
while True:
    cmd = sk.recv(1024).decode('gbk')
    if cmd == 'q':
        break
    ret = subprocess.Popen(cmd,shell=True,
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE)
    std_out =ret.stdout.read()
    std_err =ret.stderr.read()
    len_num = len(std_out)+len(std_err)
    num_by = struct.pack('i',len_num)

    sk.send(num_by)
    sk.send(std_out)
    sk.send(std_err)
sk.close()
原文地址:https://www.cnblogs.com/yzcstart/p/10598157.html