python socket

 客户端/服务器架构

即C/S架构,包括

1.硬件C/S架构(打印机)

2.软件C/S架构(web服务)

美好的愿望:

最常用的软件服务器是 Web 服务器。一台机器里放一些网页或 Web 应用程序,然后启动 服务。这样的服务器的任务就是接受客户的请求,把网页发给客户(如用户计算机上的浏览器),然 后等待下一个客户请求。这些服务启动后的目标就是“永远运行下去”。虽然它们不可能实现这样的 目标,但只要没有关机或硬件出错等外力干扰,它们就能运行非常长的一段时间。 

生活中的C/S架构:

老男孩是S端,所有的学员是C端

饭店是S端,所有的食客是C端

互联网中处处是C/S架构(黄色网站是服务端,你的浏览器是客户端;腾讯作为服务端为你提供视频,你得下个腾讯视频客户端才能看狗日的视频)

C/S架构与socket的关系:

我们学习socket就是为了完成C/S架构的开发

模拟打电话

服务端

import socket

phone = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #买手机
phone.bind(('127.0.0.1',8000))  #绑定手机卡
phone.listen(5)   #开机
print("------->")
conn,addr = phone.accept()  #等电话

msg = conn.recv(1024)   #收到消息
print("客户端发来的是",msg)
conn.send(msg.upper())   #发消息

conn.close()
phone.close()

 客户端

import socket

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

phone.connect(('127.0.0.1',8000))   #拨通电话

phone.send("hellohgjgjgjk".encode("utf-8"))   #发消息

data = phone.recv(1024)
print("收到服务端的是:",data)

phone.close()

服务端

# tcp服务端
from socket import *

ip_port = ("127.0.0.1",8080)
back_long = 5
buffer_size = 1024

tcp_sever = socket(AF_INET,SOCK_STREAM)

tcp_sever.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)   #解决重启服务端出现Address already in use

tcp_sever.bind(ip_port)

tcp_sever.listen(back_long)

while True:       #外层循环用循环接收不同的链接
    print("服务端开始运行了")
    conn,addr = tcp_sever.accept()
    print("双向链接是",conn)
    print("客户端地址是",addr)

    while True:   #内层循环用来基于一次链接循环通信
        try:
            data = conn.recv(buffer_size)
            if not data:break
            print('客户端发来的消息是 ',data.decode("utf8"))
            conn.send(data.upper())
        except Exception:
            break
    conn.close()

tcp_sever.close()

 客户端

# tcp客户端
from socket import *

ip_port = ("127.0.0.1", 8080)
buffer_size = 1024

tcp_client = socket(AF_INET, SOCK_STREAM)

tcp_client.connect(ip_port)

while True:
    msg = input(">>>").strip()
    if not msg:continue
    tcp_client.send(msg.encode("utf8"))
    print("客户端已经发消息了")
    data = tcp_client.recv(buffer_size)
    print("收到服务端发的消息是 ",data.decode("utf8"))

tcp_client.close()

服务端解决粘包

#服务端(自定制报头)

from socket import *
import subprocess
import struct
ip_port=('127.0.0.1',8080)
back_log=5
buffer_size=1024

tcp_server=socket(AF_INET,SOCK_STREAM)
tcp_server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)   #解决重启服务端出现Address already in use
tcp_server.bind(ip_port)
tcp_server.listen(back_log)

while True:
    conn,addr=tcp_server.accept()
    print('新的客户端链接',addr)
    while True:
        #收
        try:     #客户端断开,会捕捉到异常
            cmd=conn.recv(buffer_size)
            if not cmd:break
            print('收到客户端的命令',cmd)

            #执行命令,得到命令的运行结果cmd_res
            res=subprocess.Popen(cmd.decode('utf-8'),shell=True,
                                 stderr=subprocess.PIPE,
                                 stdout=subprocess.PIPE,
                                 stdin=subprocess.PIPE)
            err=res.stderr.read()
            if err:
                cmd_res=err
            else:
                cmd_res=res.stdout.read()

            #发
            if not cmd_res:
                cmd_res='执行成功'.encode('utf8')

            length=len(cmd_res)

            data_length=struct.pack('i',length)
            conn.send(data_length)
            conn.send(cmd_res)
        except Exception as e:
            print(e)
            break

 客户端解决粘包

#客户端(自定制报头)

from socket import *
import struct
from functools import partial
ip_port=('127.0.0.1',8080)
buffer_size=1024

tcp_client=socket(AF_INET,SOCK_STREAM)
tcp_client.connect(ip_port)

while True:
    cmd=input('>>: ').strip()
    if not cmd:continue
    if cmd == 'quit':break

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


    #解决粘包
    length_data=tcp_client.recv(4)
    length=struct.unpack('i',length_data)[0]   #服务端发回来的数据长度

    recv_size=0
    recv_msg=b''
    while recv_size < length:
        recv_msg += tcp_client.recv(buffer_size)
        recv_size=len(recv_msg) #1024

    print('命令的执行结果是 ',recv_msg.decode('utf8'))
tcp_client.close()

服务端  传文件

from socket import *

ip_port = ("127.0.0.1",8182)
back_long = 5
buffer_size = 1024

s = socket(AF_INET,SOCK_STREAM)
s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)
s.bind(ip_port)
s.listen(back_long)

conn,addr = s.accept()

filesize = conn.recv(buffer_size)
filesize = int(filesize)

p_size = 0
p = b""
while p_size < filesize:
    p += conn.recv(buffer_size)
    p_size = len(p)
    with open("b.jpg","wb") as f:
        f.write(p)


conn.close()
s.close()

 客户端 传文件

from socket import *
import os

ip_port = ("127.0.0.1",8182)
buffer_size = 1024

c = socket(AF_INET,SOCK_STREAM)
c.connect(ip_port)

p_size = os.stat("a.jpg").st_size
c.send(str(p_size).encode("utf8"))

with open("a.jpg","rb") as f:
    for i in f:
        # print(i)
        c.send(i)

c.close()

服务端socketserver(解决tcp多用户交流)

import socketserver

ip_port = ("127.0.0.1",8081)
buffer_size = 1024


class MyServer(socketserver.BaseRequestHandler):

    def handle(self):
        print("conn is: ",self.request)          #conn
        print("addr is:",self.client_address)    #addr

        while True:    #通信循环
            try:
                data = self.request.recv(buffer_size)
                if not data:continue
                print("客户端发来的消息是 ",data.decode("utf8"),self.client_address)

                self.request.send(data.upper())
            except Exception:
                break

if __name__ == "__main__":
    s = socketserver.ThreadingTCPServer(ip_port,MyServer)
    s.serve_forever()    #链接循环

 客户端socketserver(解决tcp多用户交流)

from socket import *

ip_port = ("127.0.0.1",8081)
buffer_size = 1024

c = socket(AF_INET,SOCK_STREAM)
c.connect(ip_port)

while True:
    msg = input(">>>:")
    c.send(msg.encode("utf8"))

    data = c.recv(buffer_size)
    print("服务发来是消息是 ",data.decode())

c.close()

udp服务端

from socket import *

ip_port = ("127.0.0.1",8080)
buffer_size = 1024

udp_sever = socket(AF_INET,SOCK_DGRAM)

udp_sever.bind(ip_port)

while True:
    data,addr = udp_sever.recvfrom(buffer_size)
    print("客户端发来的是 ",data.decode("utf8"))
    print("发消息来客户端的地址和端口是 ",addr)
    udp_sever.sendto(data.upper(),addr)

 udp客户端

from socket import *

ip_port = ("127.0.0.1",8080)
buffer_size = 1024

udp_client = socket(AF_INET,SOCK_DGRAM)

while True:
    msg = input(">>>").strip()
    udp_client.sendto(msg.encode("utf8"),ip_port)

    data,addr = udp_client.recvfrom(buffer_size)
    print("服务端发回的消息是 ",data.decode("utf8"))

udp服务端1

from socket import *
import time

ip_port = ("127.0.0.1",8080)
buffer_size = 1024

udp_sever = socket(AF_INET,SOCK_DGRAM)

udp_sever.bind(ip_port)

while True:
    data,addr = udp_sever.recvfrom(buffer_size)

    if not data:
        fmt = "%Y-%m-%d %X"
    else:
        fmt = data.decode("utf8")
    back_time = time.strftime(fmt)
    print(back_time)
    udp_sever.sendto(back_time.encode("utf8"),addr)

  udp客户端1

from socket import *

ip_port = ("127.0.0.1",8080)
buffer_size = 1024

udp_client = socket(AF_INET,SOCK_DGRAM)

while True:
    msg = input(">>>").strip()
    udp_client.sendto(msg.encode("utf8"),ip_port)

    data,addr = udp_client.recvfrom(buffer_size)
    print("服务端发回的消息是 ",data.decode("utf8"))
原文地址:https://www.cnblogs.com/liaoboshi/p/6268136.html