Python之网络编程(TCP套接字与UDP套接字)

文章目录

      • 基于tcp的套接字
          • 实现目标
          • tcp服务端源码
          • tcp客户端源码
          • tcp效果实现
      • 基于udp的套接字
          • udp作用介绍
          • udp服务端源码
          • udp客户端源码
          • udp效果实现
          • 用udp实现一个时间接收器

本篇文章继续研究Socket编程,上篇文章:Python之网络编程(socket基础)已经详细介绍过Socket编程的基础知识,其中也包括了tcp协议的工作流程。本篇就通过小案例继续分析tcp与udp的用法及功能

基于tcp的套接字

实现目标

(1)循环多链接并且循环收发消息
(2)可服务多个客户端,并且不断与客户端收发消息(但不可同时服务多个客户端,下文中的udp协议可以做到同时服务多个客户端)

tcp服务端源码
from socket import *

ip_port = ('192.168.43.247',8080)  #记录ip地址
back_log = 5
buffer_size = 1024

tcp_server = socket(AF_INET,SOCK_STREAM)

#规定服务端可以重新使用ip地址
tcp_server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)

tcp_server.bind(ip_port)  #绑定IP地址
tcp_server.listen(back_log)  #监听信号

#实现循环接收多链接,同时服务多个客户端
while True:
    #该语句用来表明状态
    print('================服务端开始运行了================')
    
    conn,addr = tcp_server.accept()  #接收对方的链接和地址
    print('双向链接是:',conn)
    print('客户端地址是:',addr)

    #实现循环收发消息
    while True:
        try:  #用异常处理来解决当服务端断开以后,跳出上一个链接的循环
            data = conn.recv(buffer_size)  #buffer_size默认参数,接收消息
            print('客户端发来的消息是:',data.decode('utf-8'))  #接收到的消息要解码
            conn.send(data.upper())  #把收到的消息变成大写
        except Exception :
            break
    conn.close()  #循环一个链接后就关闭这个链接


tcp_server.close()  #关闭socket对象
tcp客户端源码
from socket import *

ip_port = ('192.168.43.247',8080)  #记录ip地址
back_log = 5
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('utf-8'))  #发消息
    print('客户端已发送出消息!')  #接收到的消息要解码
    #接收消息
    data = tcp_client.recv(buffer_size)  #buffer_size=1024默认参数,表示字节格式
    print('服务端发回的消息是:',data.decode('utf-8'))

tcp_client.close()  #关闭socket对象
tcp效果实现

tcp服务端:
Python之网络编程(TCP套接字与UDP套接字)_第1张图片
tcp客户端:
Python之网络编程(TCP套接字与UDP套接字)_第2张图片

基于udp的套接字

udp作用介绍

(1)udp是一种没有链接的套接字,腾讯QQ就是根据udp协议通信的。

(2)为何udp套接字的服务端不需要获取对方的链接?
====>因为客户端每次发消息时都会指定发给哪个服务端

(3)recv与recvfrom的区别
recv在自己这端的缓冲区为空时,会阻断
recvfrom在自己这端的缓冲区为空时,就收一个空

(4)udp服务端的并行不冲突
udp服务端可以直接与多个客户端建立通信,不会冲突;
而tcp服务端不能直接实现并发的效果,需要特殊处理,否则只能同时服务一个客户端
原因: udp不需要建立链接,客户端每次收发都是指定好了发给哪个服务端的地址

udp服务端源码
from socket import *

ip_port = ('192.168.43.247',8080)
buffer_size = 1024  #表示字节形式

udp_server = socket(AF_INET,SOCK_DGRAM)  #SOCK_DGRAM是数据报套接字,即udp套接字
udp_server.bind(ip_port)

#因为不需要链接,所以可以直接进入循环
while True:
    #接收消息
    data,addr = udp_server.recvfrom(buffer_size)  #把内容赋给data,地址和端口赋给addr
    print('从客户端收到的消息是:',data)

    #data = udp_server.recvfrom(buffer_size)
    #这样的data是一个元组,里面包括了,内容,服务端的ip地址,服务端的端口

    #服务端发回客户端消息
    udp_server.sendto(data.upper(),addr)  #addr是对方的地址和端口
udp客户端源码
from socket import *

ip_port = ('192.168.43.247',8080)
buffer_size = 1024  #表示字节形式

udp_client = socket(AF_INET,SOCK_DGRAM)  #SOCK_DGRAM是数据报套接字,即udp套接字

#开始循环收发消息
while True:
    msg = input('请输入>>>')  #指定输入消息
    udp_client.sendto(msg.encode('utf-8'),ip_port)
    #udp套接字需要用sendto发消息,第一个参数是消息内容,第二个参数是服务端的ip地址
    #这样就可以让客户端每次都发给指定的服务端,而服务端不需要获取客户端的链接

    #客户端接收消息
    data,addr = udp_client.recvfrom(buffer_size)  #以字节形式接收消息
    #因为收到的是一个元组,所以把内容赋给data,地址赋给addr
    print(data.decode('utf-8'))  #解码并输出消息
udp效果实现

客户端:
Python之网络编程(TCP套接字与UDP套接字)_第3张图片
客户端并发:
Python之网络编程(TCP套接字与UDP套接字)_第4张图片

用udp实现一个时间接收器

每发送一次请求就返回一个时间
Python之网络编程(TCP套接字与UDP套接字)_第5张图片
原理就是上文的udp服务端与客户端代码,文章里传上了py文件,需要的请自行下载

你可能感兴趣的:(Python进阶者,socket,python,udp,程序人生,经验分享)