python-socket tcp循环-半连接池-socket udp模板

文章目录

      • 一、TCP基础版
      • 二、TCP循环版
      • 三、TCP异常处理
      • 四、半连接池
      • 五、UDP模板

一、TCP基础版

服务端:

import socket

#买手机 默认得到是一个TCP的socket
server = socket.socket()

#绑定手机卡
server.bind(("127.0.0.1",16888))

#开始待机
server.listen()

# 得到对方的socket对象与地址
client,addr = server.accept()

print('===============')
#buffersize 表示应用程序的缓冲区大小 recv其实是从系统缓冲区读取数据到应用程序
data = client.recv(1024)
print('===============')
print("收到客户端发来的数据:%s" % data.decode("utf-8"))
client.send(data)

client.close()
server.close()

客户端:

import socket
client = socket.socket()
client.connect(('127.0.0.1',16888))
client.send('hello 服务器'.encode('utf-8'))

print('===========================')
data = client.recv(1024)
print('===========================')
print("收到服务器:%s" % data.decode("utf-8"))
client.close()

二、TCP循环版

服务端:

import socket

server = socket.socket()
server.bind(('127.0.0.1',16888))
server.listen()

#连接循环,可以不断接受新连接
while True:
    client,addr = server.accept()
    #通讯循环,可以不断的收发数据
    while True:
        try:
            #如果是windows,对方强行关闭连接,会抛出异常
            #如果是linux,不会抛出异常,会死循环收到空的数据包

            data = client.recv(1024)
            if not data:
                client.close()
                break
            print("收到客户端发来的数据:%s" % data.decode("utf-8"))
            client.send(data)
        except ConnectionResetError:
            print('客户端强行关闭了连接')
            client.close()
            break
client.close()
server.close()

客户端:

import socket

client = socket.socket()
client.connect(('127.0.0.1',16888))
while True:
    msg = input('>>>:')
    client.send(msg.encode('utf-8'))
    data = client.recv(1024)
    print("收到服务器:%s" % data.decode("utf-8"))

client.close()

三、TCP异常处理

服务端:

import  socket

server = socket.socket()
server.bind(("127.0.0.1",8888))
server.listen()
client,addr = server.accept()

while True:
    try:
        data = client.recv(1024)
        if not data:
            print("对方已经关闭.....")
            break
        print(data.decode("utf-8"))
        client.send(data.upper())
    except ConnectionResetError:
        print("对方异常关闭连接...")

client.close()
server.close()

客户端:

import  socket

client = socket.socket()
client.connect(("127.0.0.1",8888))
client.send("hello".encode("utf-8"))
data = client.recv(1024)
print(data.decode("utf-8"))

client.close()

四、半连接池

  1. 什么是半连接池:当服务器在响应了客户端的第一次请求后会进入等待状态,会等客户端发送的ack信息,这时候这个连接就称之为半连接
  2. 半连接池其实就是一个容器,系统会自动将半连接放入这个容器中,可以避免半连接过多而保证资源耗光
  3. 产生半连接的两种情况:
    1. 客户端无法返回ACK信息
    2. 服务器来不及处理客户端的连接请求

服务端:

#模拟服务器来不及处理客户端的连接请求
import  socket
import time

server = socket.socket()

server.bind(("127.0.0.1",8888))

# 参数可以设置最大的半连接数,最大2个
server.listen(2)

while True:
    time.sleep(0.5)

server.close()

客户端:

import socket

client = socket.socket()
client.connect(("127.0.0.1",8888))

while True:
    client.send(input(">>>:").encode("utf-8"))
    data = client.recv(1024)
    print(data.decode("utf-8"))

client.close()

五、UDP模板

服务端:

import socket

# UDP协议在创建socket时只有一个类型不同
server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,proto=0)
server.bind(("127.0.0.1",8888))


while True:
    data,addr = server.recvfrom(1024) # 阻塞直到收到数据为止
    print("收到来自%s的消息:%s" % (data.decode("utf-8"),addr))
    # 返回值为数据和对端ip地址、端口号
    server.sendto(data.upper(),addr)

print(res)
server.close()
import socket

client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)

while True:
    data = input(">>>:").encode("utf-8")
    client.sendto(data,("127.0.0.1",8888))
    d,addr = client.recvfrom(1024)
    print(d.decode("utf-8"))

client.close()

练习:

'''
1.整理tcp三次握手、四次挥手图
2.使用UDP完成多人聊天,服务器收到消息后,将客户端地址存储在容器中,再将消息转发给容器中的每个客户端。注意:容器中每个不同的客户端地址仅存储一份,以避免重复发送,建议使用集合或字典来存储
3.基于TCP开发一款远程CMD程序,客户端连接服务器后,可以向服务器发送命令,服务器收到命令后执行,无论执行成功还是失败将执行结果返回给客户端,执行系统指令使用subprocess模块完成
4.开发一款基于UDP时间服务器,客户端可以指定需要获取的时间格式。如:"YYYY-MM-DD HH:mm:ss"
'''
==========================================================
#第一题
三次握手:第一次客户端请求数据报文,第二次服务端确认客户端请求,发送确认信息和测试数据,第三次客户端收到服务端的请求,发送确认信息,正式建立连接。
四次挥手:第一次挥手客户端发送关闭连接请求,第二次挥手服务端发送到接受客户端的信息,第三次挥手服务端发送确认断开连接信息,第四次挥手客户端确认信息完整。




===========================================================
#第二题
#udp服务端
import socket

client_dic = {}
server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,proto=0)
server.bind(("127.0.0.1",8888))

while True:
    data,addr = server.recvfrom(1024)
    print("服务器收到了%s 发来的%s" % (addr,data.decode("utf-8")))
    # 将客户端加入字典
    client_dic[addr] = addr

    # 转发给除自己以外的所有客户端
    for add in client_dic:
        if addr != add:
            server.sendto(data,add)

--------------------------------------------------------------         
#udp客户端
import socket

# 服务器的地址
addr = ("127.0.0.1",8888)
c = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)

while True:
    msg = input(">>>:").strip()
    c.sendto(msg.encode("utf-8"),addr)
    data,s_addr = c.recvfrom(1024)
    print(data.decode("utf-8"))
    
    
    
    
===========================================================
#第三题
#tcp服务端
import  socket
import subprocess

server = socket.socket()
server.bind(("127.0.0.1",9090))
server.listen()

while True:
    client,addr = server.accept()
    while True:
        try:
            # 接收命令
            cmd = client.recv(1024).decode("utf-8")
            p = subprocess.Popen(cmd,shell=True,stdout=-1,stderr=-1)
            # data与err_data 都是采用的系统编码 windows是GBK
            data = p.stdout.read()
            err_data = p.stderr.read()

            client.send(data)
            client.send(err_data)
        except ConnectionResetError:
            client.close()
            print("连接中断......")
            break
----------------------------------------------------------------------------
#tcp客户端
import socket

c = socket.socket()
c.connect(("127.0.0.1",9090))
while True:
    cmd = input(">>:").strip()
    c.send(cmd.encode("utf-8"))
    data = c.recv(1024)
    print(data.decode("gbk"))
    
    
    
    
========================================================
#第四题
#udp时间服务端
import socket
import time

server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
server.bind(("127.0.0.1",7777))

while True:
    data,addr = server.recvfrom(1024)
    form = data.decode("utf-8")
    t = time.time()
    try:
        time_str = time.strftime(form,time.localtime(t))
        server.sendto(time_str.encode("utf-8"), addr)
    except Exception as e:
        print(e)
        server.sendto("格式错误...".encode("utf-8"), addr)
---------------------------------------------------------------
#udp时间客户端
import socket

addr = ("127.0.0.1",7777)
c = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)

while True:
    msg = input(">>>:").strip()
    c.sendto(msg.encode("utf-8"),addr)
    data,s_addr = c.recvfrom(1024)
    print(data.decode("utf-8"))

你可能感兴趣的:(Python学习)