簡體   English   中英

Python UDP服務器發送文本文件的行

[英]Python UDP Server send lines of a text file

我需要模擬一個UDP服務器,該服務器以無限循環的方式逐行發送文本文件的內容。 我已經在下面編寫了代碼,但另一方面我什么也沒收到(另一面是Qt代碼,我確定它可以工作):

import socket
import time

# setup UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sa = ('localhost', 9763)
sock.bind(sa)

filename = '/home/saeid/Documents/data.txt'  # file to read
numlines = sum(1 for line in open(filename))  # get number of lines in file


# get line of a file
def get_line(line):
    with open(filename) as fp:
        for i, l in enumerate(fp):
            if i == line:
                return l

# main loop
while True:
    currline = 0
    while currline < numlines:
        sock.sendto(get_line(currline), sa)
        currline += 1
        time.sleep(1)

我不是python pro,無法解決問題:(

對於初學者來說,這很混亂:

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sa = ('localhost', 9763)
sock.bind(sa)
...
sock.sendto(get_line(currline), sa)

通過綁定,您基本上會說“我想在該主機/端口上監聽”。 但是隨后您將數據發送到同一主機/端口。 我假設還有其他目標地址,例如sock.sendto(get_line(currline), ('my_host', 1234)) 順便說一句,為什么仍然要綁定到該地址? sock.bind(sa)行是不必要的,請將其刪除。


另一件事是您的文件讀取代碼效率極低並且難以閱讀(花了我一段時間才了解正在發生的事情)。 嘗試這樣的事情:

with open(filename, 'r') as fo:
    while True:
        for line in fo:
            sock.sendto(line, DEST_ADDRESS)
            time.sleep(1)
        fo.seek(0)  # go back to the begining of the file and repeat

並擺脫get_line函數。

至少那是我在閱讀您的描述后想到的。 如果您不希望無限發送相同的文件,則可以刪除while True: loop和fo.seek(0)調用。

谷歌叔叔提出了用戶數據報客戶端和服務器

用戶數據報客戶端和服務器

用戶數據報協議(UDP)的工作原理不同於TCP / IP。 在TCP是面向流的協議的情況下,確保所有數據都以正確的順序傳輸,而UDP是面向消息的協議。 UDP不需要長壽命的連接,因此設置UDP套接字要簡單一些。 另一方面,UDP消息必須容納在單個數據包中(對於IPv4,這意味着它們只能容納65,507字節,因為65,535字節的數據包還包含標頭信息),並且不能像TCP那樣保證傳遞。

回聲服務器

由於本身沒有連接,因此服務器不需要偵聽和接受連接。 它只需要使用bind()將其套接字與端口關聯,然后等待單獨的消息。

import socket
import sys

# Create a TCP/IP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

# Bind the socket to the port
server_address = ('localhost', 10000)
print >>sys.stderr, 'starting up on %s port %s' % server_address
sock.bind(server_address)

使用recvfrom()從套接字讀取消息,該消息返回數據以及從中發送數據的客戶端地址。

while True:
    print >>sys.stderr, '\nwaiting to receive message'
    data, address = sock.recvfrom(4096)

    print >>sys.stderr, 'received %s bytes from %s' % (len(data), address)
    print >>sys.stderr, data

    if data:
        sent = sock.sendto(data, address)
        print >>sys.stderr, 'sent %s bytes back to %s' % (sent, address)

回聲客戶端

UDP回顯客戶端與服務器類似,但是不使用bind()將其套接字附加到地址。 它使用sendto()將其消息直接傳遞到服務器,並使用recvfrom()接收響應。

import socket
import sys

# Create a UDP socket
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

server_address = ('localhost', 10000)
message = 'This is the message.  It will be repeated.'

try:

    # Send data
    print >>sys.stderr, 'sending "%s"' % message
    sent = sock.sendto(message, server_address)

    # Receive response
    print >>sys.stderr, 'waiting to receive'
    data, server = sock.recvfrom(4096)
    print >>sys.stderr, 'received "%s"' % data

finally:
    print >>sys.stderr, 'closing socket'
    sock.close()

客戶端和服務器一起

運行服務器會產生:

$ python ./socket_echo_server_dgram.py

starting up on localhost port 10000

waiting to receive message
received 42 bytes from ('127.0.0.1', 50139)
This is the message.  It will be repeated.
sent 42 bytes back to ('127.0.0.1', 50139)

waiting to receive message

客戶端輸出為:

$ python ./socket_echo_client_dgram.py

sending "This is the message.  It will be repeated."
waiting to receive
received "This is the message.  It will be repeated."
closing socket

$

您需要在調用sendto的呼叫中更改目標地址或端口:

        peer_address = ('localhost', peer_port)
        sock.sendto(get_line(currline), peer_address)

Qt應用程序綁定到哪個地址和端口?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM