UDP协议 并发编程

一.TCP半连接池原理

  半连接池的工作原理

  目前我们的程序是单线程  服务器要么处理通讯要么处理连接请求 无法同时进行

#服务器

import socket
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(("127.0.0.1",9999))
# 不是罪大连接数
server.listen(5)
while True:
    c,addr = server.accept
    while True:
        try:
            msg = c.recv(1024).decode("utf-8")
            if not msg:
                c.close()
                break
            c.send(msg.upper().encode("utf-8"))
        except BaseException:
            print("客户端异常断开")
            c.close()
server.close()


#用户端

import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(("127.0.0.1",9999))
while True:
    data = input(">>>:")
    if not data:coninue
    client.send(data.encode("utf-8")
    print(msg)
client.close()

二.TCP 和 UDP 发送数据是的流程

  解释 为何TCP是可靠的 是因为发送数据后必须受到确认包

#服务器

import socket
#创建socket对象 指定type参数为socket.SOCK_DGRAM表示使用UDP协议
server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)#datagram数据报的意思
# 绑定ip和端口
server.bind(("127.0.0.1",8888))
while True:
    # 接受数据 返回一个元祖  数据和  发送方的地址
    msg,c_adde = server.recvfrom(1024)
    print("收到来自%s: 说:%s"%(c_addr[0],msg.decode("utf-8")))
    # 发送数据到指定ip和端口
    server.sendto(msg.upper(),c_addr)


#客户端
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
    msg = input(">>>:")
    client.sendto(msg.encode("utf-8"),("127.0.0.1",8888))
    print(data.decode("utf-8")

三.UDP聊天

  与TCP代码的区别

  不需要监听 不需要接收

  type参数为 SOCK_DGRAM

  UDP 可以同时处理多个客户端 是因为CPU处理速度快 给人感觉像同时处理

  群聊

    1.客户端先把数据交给服务器

    2.服务器先存储对方的地址

    3.把收到的数据给所有人都发一遍

#服务器

import socket
server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server.bind(("127.0.0.1",8848))

#如果客户端与服务器同一台计算机  并且有多个客户端  这些客户端ip都是相同127.0.0.1
clients = {}
while True:
    msg,addr = server.recvfrom(1024)
    # 存储对方的地址:
    clients[addr[1]] = addr
    print(msg.decode("utf-8"))
    #循环发给所有人
    for c in clients:
        server.sendto(msg,clients[c])

#客户端1
import socket
c = coket.c=soket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
    msg= input(">>>:")
    c.sendto(msg.encode("utf-8"),("127.0.0.1",8848))
    msg,addr = c.recvfrom(1024)
    print(msg.decode("utf-8"))
#客户端2
import socket
c = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
    msg = input(">>>:"
    c.sendto(msg.encode("utf-8"),("127.0.0.1",8848))
    msg,addr = c.recvfrom(1024)
    print(msg.decode("utf-8"))

UDP聊天2

#服务器
import socket
server = socket.socket(socket.AF_INET,sccket.SOCK_DGRAM)
server.bind(("127.0.0.1",8848))
clients={}
while True:
    msg,addr = server.recvfrom(1024)
    clients[addr[1]] = addr

    print(msg.decode("utf-8"))
    for c in clients:
        server.sendto(msg,clients[c])

#发送机
import socket
c = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
while True:
    msg = input(">>>:")
    c.sendto(msg.encode("utf-8"),("127.0.0.1",8848)

#接收机
import socket
c = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
#先随便发一条消息给服务器  让服务指导自己的地址
c.sendto("register".encode("utf-8"),("127.0.0.1",8848))
while True:
    msg,addr = c.recvfrom(1024)
    print(msg.decode("utf-8"))
    

6.UDP会粘包么?

#服务器

import socket
server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
server.bind(("127.0.0.1",8888))
while True:
    msg,c_addr = server.recvfrom(512)
    
    print("收到自己%: 说:%s"%(c_addr[0],msg.decode("utf-8")))
    server.sendto(msg.upper(),c_addr)

#客户端
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
client.sendto("10".encode("utf-8"),("127.0.0.1"8888))
client.sendto("22".encode("utf-8"),("127.0.0.1"8888))
client.sendto("32".encode("utf-8"),("127.0.0.1"8888))
client.sendto("43".encode("utf-8"),("127.0.0.1"8888))

结论:

  1.UDP 不粘包

  2.缓冲区大小要足够装数据包大小 建议不要超过512

UDP的使用场景: 视频电话 语音电话  直播

DNS   域名解析服务器

 

做一个时间服务器 使用UDP协议  客户端请求服务器获取当前时间

#服务端
import socket
import time
# 创建socket对象  指定type参数为socket.SOCK_DGRAM 表示使用UDP协议
server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) # datagram数据报的意思
# 绑定ip和端口
server.bind(("127.0.0.1",8889))

while True:
    # 接收数据 返回一个元祖  数据和 发送方的地址
    msg,c_addr = server.recvfrom(1024)
    msg=time.strftime("%Y-%m-%d %X").encode("utf-8")
    print("%s 收到来自%s: 说:%s" % (time.strftime("%Y-%m-%d %X"),c_addr[0] ,msg.decode("utf-8")))
    print(type(msg))
    # 发送数据到指定ip和端口
    server.sendto(msg.upper(),c_addr)

#用户端
import socket

client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # datagram数据报的意思

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

 

posted @ 2018-11-06 17:31  Milford  阅读(271)  评论(0编辑  收藏  举报