码迷,mamicode.com
首页 > 其他好文 > 详细

2018-10-10 socket网络编程——udp与tcp

时间:2018-10-30 13:11:25      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:执行   现在   检测   分享   准备   必须   .so   data   检查   

------------------------------------------------------------UDP------------------------------------------------------------

因为udp发送数据之前不需要建立连接所有具有以下特点

无连接

资源开销小

传输速度快

udp每个数据包最大是64K

UDP的优缺点

  优点:

    传输速度快

    不需要连接,资源开销小

  缺点:

    传输数据不可靠,容易丢数据包

    没有流量控制,当对方没有及时接收数据,发送方一直发送数据会导致缓冲区数据满了,电脑出现卡死情况,所有接收方需要及时接收数据。

UDP的使用场景

  当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP

    qq音视频传输,微信音视频传输

    上课使用的共屏软件

    发送广播消息

UDP通信流程:

技术分享图片

UDP发送、接受数据:

import socket

# 1. 创建udp套接字
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# 2. 准备接收方的地址
dest_addr = (192.168.236.129, 8080)

# 3. 从键盘获取数据
send_data = input("请输入要发送的数据:")

# 4. 发送数据到指定的电脑上
udp_socket.sendto(send_data.encode(utf-8), dest_addr)

# 5. 等待接收对方发送的数据
recv_data = udp_socket.recvfrom(1024)  # 1024表示本次接收的最大字节数

# 6. 显示对方发送的数据
# 接收到的数据recv_data是一个元组
# 第1个元素是对方发送的数据
# 第2个元素是对方的ip和端口
print(recv_data[0].decode(gbk))
print(recv_data[1])

# 7. 关闭套接字
udp_socket.close()

 

 

 

 

案例-udp聊天器

import socket


def send_msg(udp_socket):
    """获取键盘数据,并将其发送给对方"""
    # 1. 从键盘输入数据
    msg = input("\n请输入要发送的数据:")
    # 2. 输入对方的ip地址
    dest_ip = input("\n请输入对方的ip地址:")
    # 3. 输入对方的port
    dest_port = int(input("\n请输入对方的port:"))
    # 4. 发送数据
    udp_socket.sendto(msg.encode("utf-8"), (dest_ip, dest_port))


def recv_msg(udp_socket):
    """接收数据并显示"""
    # 1. 接收数据
    recv_msg = udp_socket.recvfrom(1024)
    # 2. 解码
    recv_ip = recv_msg[1]
    recv_msg = recv_msg[0].decode("utf-8")
    # 3. 显示接收到的数据
    print(">>>%s:%s" % (str(recv_ip), recv_msg))


def main():
    # 1. 创建套接字
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # 2. 绑定本地信息
    udp_socket.bind(("", 7890))
    while True:
        # 3. 选择功能
        print("="*30)
        print("1:发送消息")
        print("2:接收消息")
        print("="*30)
        op_num = input("请输入要操作的功能序号:")

        # 4. 根据选择调用相应的函数
        if op_num == "1":
            send_msg(udp_socket)
        elif op_num == "2":
            recv_msg(udp_socket)
        else:
            print("输入有误,请重新输入...")

if __name__ == "__main__":
    main()

 

 

 

 

------------------------------------------------------------TCP------------------------------------------------------------

TCP特点

  面向连接

    通信双方必须先建立连接才能进行数据的传输,双方都必须为该连接分配必要的系统内核资源,以管理连接的状态和连接上的传输

    双方间的数据传输都可以通过这一个连接进行

    完成数据交换后,双方必须断开此连接,以释放系统资源

    这种连接是一对一的,因此TCP不适用于广播的应用程序,基于广播的应用程序请使用UDP协议

  可靠传输

    1.TCP采用发送应答机制

      TCP发送的每个报文段都必须得到接收方的应答才认为这个TCP报文段传输成功

    2.超时重传

      发送端发出一个报文段之后就启动定时器,如果在定时时间内没有收到应答就重新发送这个报文段

      TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包             发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重             传

    3.错误校验

      由发送端计算,然后由接收端验证,其目的是为了检测数据在发送端到接收端之间是否有改动,如果接收方检测到校验和有差错,则直接丢弃             这数据包

    4.流量控制和阻塞管理

      流量控制用来避免主机发送得过快而使接收方来不及完全收下

  TCP的优缺点

    优点:

      可靠,稳定

      适合传输大量数据

        缺点:

      传输速度慢

      占用系统资源高

  TCP和UDP区别

    TCP面向连接; UDP是不面向连接

    TCP提供可靠的数据传输,也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP不保证可靠的数据传输,容易出现丢         包情况

    TCP需要连接传输速度慢,UDP不需要连接传输速度快

    TCP不支持发广播;UDP支持发广播

    TCP对系统资源要求较多,UDP对系统资源要求较少

    TCP适合发送大量数据,UDP适合发送少量数据

    TCP有流量控制,UDP没有流量控制

  TCP使用场景

    当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传             输文件的协议,POP、SMTP等邮件传输的协议

    在日常生活中,常见使用TCP协议的应用如下:

      浏览器

      QQ文件传输

TCP通信流程:

技术分享图片

案例-TCP文件下载器

服务端

import socket
import os

if __name__ == __main__:
    # 创建tcp服务端socket
    tcp_serve_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置socket选项,防止程序退出端口不立即释放的问题
    tcp_serve_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口
    tcp_serve_socket.bind(("", 9090))
    # 设置监听,把主动套接字改成被动套接字,被动套接字只能接收客户端的连接请求,不能收发消息
    tcp_serve_socket.listen(128)
    # 循环接收客户端的连接请求, 提示:现在的下载是同步下载,一个用户下载完成以后另外一个用户才能下载
    while True:
        # 接收客户端的连接请求
        service_client_socket, ip_port = tcp_serve_socket.accept()
        # 代码执行到说明解阻塞,说明连接建立成功
        file_name_data = service_client_socket.recv(1024)
        # 解码数据
        file_name = file_name_data.decode("gbk")
        print(file_name, ip_port)
        if os.path.exists(file_name):
            # 文件存在
            with open(file_name, "rb") as file:
                # 读取文件数据
                while True:
                    file_data = file.read(1024)
                    if file_data:
                        # 发送文件数据给客户端
                        service_client_socket.send(file_data)
                    else:
                        break
        else:
            print("文件不存在")
        # 终止和客户端服务
        service_client_socket.close()
    # 终止提供处理连接请的服务
    tcp_serve_socket.close()

 

 

 

 

客户端

import socket

if __name__ == __main__:
    # 创建tcp客户端socket
    tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 建立连接
    tcp_client_socket.connect(("192.168.107.160", 9090))
    # 获取用户输入文件名
    file_name = input("请输入您要下载的文件名:")
    # 使用gbk进行编码
    file_name_data = file_name.encode("gbk")
    # 代码执行到此,说明连接建立成功
    tcp_client_socket.send(file_name_data)
    with open("/home/python/Desktop/" + file_name, "wb") as file:
        # 循环接收服务端发送的文件二进制数据
        while True:
            # 获取服务端文件数据
            file_data = tcp_client_socket.recv(1024)
            if file_data:
                # 写入到指定文件
                file.write(file_data)
            else:
                break

    # 关闭socket
    tcp_client_socket.close()

 

 

 

 

TCP三次握手:

技术分享图片

 

标志位

  SYN: 表示连接请求 ACK: 表示确认 FIN: 表示关闭连接 seq:表示报文序号 ack: 表示确认序号

小结:

  第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。

  第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack (number )=J+1,随机产生一个                 值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。

  第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server                检ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server                之间可以开始传输数据了。

TCP四次挥手:

技术分享图片

 

小结:

 

  第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送。

  第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1。

  第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送。

  第四次挥手:Client收到FIN后,接着发送一个ACK给Server,确认序号为收到序号+1。

2018-10-10 socket网络编程——udp与tcp

标签:执行   现在   检测   分享   准备   必须   .so   data   检查   

原文地址:https://www.cnblogs.com/z0806/p/9875950.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!