当前位置: 首页 > 知识库问答 >
问题:

Python 中的 UDP 客户端/服务器套接字

毋澄邈
2023-03-14

我是 python 和套接字的新手,正在尝试编写一个回显客户端/服务器套接字。我已经编写了服务器,以便丢失 30% 的数据包。我将客户端编程为在一秒后超时,因为数据包可能会丢失。但是,每当我运行客户端套接字时,我的输出都是 100% 请求超时。我假设我得到这个输出,因为我的服务器从未收到过消息。我已经多次查看了我的代码,但无法弄清楚为什么我不断获得此输出。下面是我的服务器和客户端套接字的代码。任何帮助将不胜感激。

服务器套接字:

 # We will need the following module to generate randomized lost packets
    import random
    from socket import *

    # Create a UDP socket
    # Notice the use of SOCK_DGRAM for UDP packets
    serverSocket = socket(AF_INET, SOCK_DGRAM)

    # Assign IP address and port number to socket
    serverSocket.bind(('', 12000))

    while True:
        # Generate random number in the range of 0 to 10
        rand = random.randint(0, 10)

        # Receive the client packet along with the address it is coming from
        message, address = serverSocket.recvfrom(1024)

        # Capitalize the message from the client
        message = message.upper()

        # If rand is less is than 4, we consider the packet lost and do notrespond
        if rand < 4:
            continue

        # Otherwise, the server responds
        serverSocket.sendto(message, address) 

客户端套接字:

import time
from socket import *

pings = 1

#Send ping 10 times 
while pings < 11:  

    #Create a UDP socket
    clientSocket = socket(AF_INET, SOCK_DGRAM)

    #Set a timeout value of 1 second
    clientSocket.settimeout(1)

    #Ping to server
    message = 'test'

    addr = ("127.0.0.1", 12000)

    #Send ping
    start = time.time()
    clientSocket.sendto(message, addr)

    #If data is received back from server, print 
    try:
        data, server = clientSocket.recvfrom(1024)
        end = time.time()
        elapsed = end - start
        print data + " " + pings + " "+ elapsed        

    #If data is not received back from server, print it has timed out  
    except timeout:
        print 'REQUEST TIMED OUT'

    pings = pings - 1

共有2个答案

方兴旺
2023-03-14

这是 asyncio 的替代方案。

import asyncio
import random

class EchoServerProtocol:
    def connection_made(self, transport):
        self.transport = transport

    def datagram_received(self, data, addr):
        message = data.decode()
        print('Received %r from %s' % (message, addr))
        rand = random.randint(0, 10)
        if rand >= 4:
            print('Send %r to %s' % (message, addr))
            self.transport.sendto(data, addr)
        else:
            print('Send %r to %s' % (message, addr))
            self.transport.sendto(data, addr)


loop = asyncio.get_event_loop()
print("Starting UDP server")

# One protocol instance will be created to serve all client requests
listen = loop.create_datagram_endpoint(
    EchoServerProtocol, local_addr=('127.0.0.1', 12000))
transport, protocol = loop.run_until_complete(listen)

try:
    loop.run_forever()
except KeyboardInterrupt:
    pass

transport.close()
loop.close()
卜方伟
2023-03-14

我测试了你的代码,它在我的机器上正常工作。你的问题可能不是你的代码。可能是防火墙或其他东西阻挡了环回接口(127.0.0.1)上的所有数据包。根据您的操作系统,尝试使用Wireshark之类的数据包监视器进行测试。

此外,这里有一些关于如何改进代码以使其更Pythonic的建议:

服务器

import random
import socket

server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(('', 12000))

while True:
    rand = random.randint(0, 10)
    message, address = server_socket.recvfrom(1024)
    message = message.upper()
    if rand >= 4:
        server_socket.sendto(message, address)

客户

import time
import socket

for pings in range(10):
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    client_socket.settimeout(1.0)
    message = b'test'
    addr = ("127.0.0.1", 12000)

    start = time.time()
    client_socket.sendto(message, addr)
    try:
        data, server = client_socket.recvfrom(1024)
        end = time.time()
        elapsed = end - start
        print(f'{data} {pings} {elapsed}')
    except socket.timeout:
        print('REQUEST TIMED OUT')
 类似资料:
  • 我已经在Minikube上部署了一个UDP套接字服务器。套接字服务绑定到端口2152。下面是description pod命令中的IP片段。 我的客户机与minikube运行在同一个VM上,无法与服务器通信。我在客户端使用服务器地址IP 172.17.0.3,端口为2152。我还尝试使用minikube IP 192.168.49.2将UDP数据从客户端发送到服务器。 请帮忙,这里有什么问题。

  • 我试图用java实现一个客户端服务器,在这里我读取客户端中的输入并在服务器中执行UperCase,然后返回客户端并打印UperCase。我使用ObjectOutputStream和ObjectInputStream进行读写,但是当我在客户机中键入一个msg时,程序会显示以下错误: Digite uma msg casa java.io.eofexception位于java.io.datainput

  • 我对使用UDP协议的服务器和客户端之间的通信有一个非常奇怪的问题。客户端是用Mono2x编写的(我使用Unity 3D作为我的客户端)并创建Udp客户端类实例: 我的服务器是 UWP 应用程序,我想在使用 DatagramSocket 的 Raspberry Pi 上运行: 我将数据从客户端发送到服务器,但运气不佳。我用TCPView检查了数据是从我的客户端应用程序发送的,但从未到达服务器。现在是

  • 我对套接字有点陌生,我正在尝试编写一个程序,在这个程序中,我基本上可以从客户端程序向服务器程序发送一些简单的请求。现在我只想在客户端有1或2个选项供用户选择。例如,如果用户在客户端选择“选项1”,那么服务器会返回一条消息“您选择选项1”,以此类推,但我不知道如何读取服务器上从客户端发送的输入。 客户代码: 服务器代码: 我需要在Clinet中使用两个不同的BufferedReader吗?一个用于用

  • 正在编写一个服务器,使用Java套接字的客户端聊天程序。这是我的服务器套接字类的代码。 客户端能够建立连接并向服务器发送消息。服务器也可以接收客户端发送的消息。问题是当消息从服务器发送时,客户端没有收到消息。这是我的客户端套接字代码。

  • 问题内容: 我正在构建一个小型聊天应用程序,其中客户端A希望通过服务器B将某些东西发送到客户端C。首先,这是解决问题的正确方法吗?我能够向服务器发送数据或从服务器接收数据,但仅限于客户端。例如,如果客户端A向服务器B发送数据而客户端C向服务器B发送数据,则我可以将数据发送回服务器A和C就像回显服务器一样。但是我想要的是将来自客户端A的数据通过服务器B转发到客户端C。 以下是服务器代码: 客户端代码