learn tcp udp

101 阅读3分钟
# -*- coding: utf-8 -*-

import socket

import threading

  


# 启动往 8172 端口发送数据的服务

def send_data():

    # 创建 TCP 套接字

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

    # 绑定 IP 地址和端口号

    s.bind(('127.0.0.1', 8172))

    # 开始监听连接

    s.listen()

    print('Send data server started.')

    # 等待连接

    conn, addr = s.accept()

    print('Connected by', addr)

    # 发送数据

    conn.sendall(b'Hello, world!')

    # 关闭连接

    conn.close()

  


# 启动从 8172 端口获取数据的服务

def get_data():

    # 创建 TCP 套接字

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

    # 连接到目标主机和端口号

    s.connect(('127.0.0.1', 8172))

    print('Get data server started.')

    # 接收数据

    data = s.recv(1024)

    print('Received', data.decode())

    # 关闭连接

    s.close()

  


# 启动两个服务

t1 = threading.Thread(target=send_data)

t2 = threading.Thread(target=get_data)

t1.start()

#t2.start()

如上,如果只发送数据,启动服务

python .\test\bci2000\udp_server.py

会一直hang在下面这行代码

conn, addr = s.accept()

image.png 服务会一直等待接收程序的连接

这个时候如果在其他terminal里面测试8172端口的连通性,会接收到发送服务的数据,发送服务也会继续向下执行 image.png

image.png

如果注释掉发送服务的线程开启,打开接受数据的线程,执行文件之后会报错

image.png

因为这个端口号没有被开启

还有一个知识点,如果把tcp套接字换成udp套接字,程序走到listen这里会报错 image.png 因为UDP协议是面向无连接的,因此UDP套接字是不能像TCP套接字那样使用listen()方法进行监听的。listen()方法是用于TCP套接字的,它使得TCP套接字可以开始监听来自客户端的连接请求,并准备接受这些连接。但是,UDP套接字并不需要进行连接的建立,因此也就没有必要使用listen()方法进行监听。

相反,UDP套接字通常使用bind()方法将套接字绑定到一个固定的IP地址和端口号,以便可以从该地址和端口接收数据报。然后,可以使用recvfrom()方法从套接字接收数据报,或者使用sendto()方法向指定的目标地址和端口发送数据报。

因此,如果您需要使用UDP套接字来接收或发送数据报,您只需要使用bind()方法将套接字绑定到合适的地址和端口即可。但是请注意,由于UDP是无连接的,因此您将需要在您的代码中自己处理数据报的排序、重传、丢失等问题。


image.png 使用命令查看目前端口使用情况,会发现4个部分,有协议,本地地址,外部地址,状态,TCP连接,连接状态包括"ESTABLISHED"、"SYN_SENT"、"SYN_RECEIVED"、"FIN_WAIT_1"、"FIN_WAIT_2"、"TIME_WAIT"、"CLOSE_WAIT"、"LAST_ACK"和"CLOSED"等状态。对于UDP连接,不会有连接状态这一栏。,所以千万不要做在过滤udp端口的同时还过滤状态栏的傻事,会一无所获

image.png


在同一台计算机上,同一个UDP端口只能被一个进程占用并监听。如果尝试在同一端口上启动另一个进程来监听UDP流量,那么会出现端口冲突的错误。因此,同一UDP端口只能被一个进程监听,如果需要多个进程监听同一端口,可以使用多播(multicast)或广播(broadcast)等技术。

在工作中写了一个脚本监听4001端口

image.png

然后启动bci2000,因为其中有个程序需要监听4001端口,所以启动会报错

image.png