1

テキスト ファイルのコンテンツを 1 行ずつ無限ループで送信する 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のプロではなく、問題を理解できません:(

4

3 に答える 3

4

手始めに、これはめちゃくちゃです:

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)行は不要ですので削除してください。


もう 1 つは、ファイル読み取りコードが非常に非効率的で読みにくいことです (何が起こっているのかを理解するのに時間がかかりました)。次のようなことを試してください:

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:ループとfo.seek(0)呼び出しを取り除くことができます。

于 2016-11-01T17:46:45.817 に答える
1

Google おじさんがUser Datagram Client と Serverを思いついた

ユーザー データグラム クライアントとサーバー

ユーザー データグラム プロトコル (UDP) は、TCP/IP とは異なる動作をします。TCP がストリーム指向のプロトコルであり、すべてのデータが正しい順序で送信されることを保証するのに対し、UDP はメッセージ指向のプロトコルです。UDP は長時間の接続を必要としないため、UDP ソケットの設定は少し簡単です。一方、UDP メッセージは 1 つのパケットに収まる必要があり (IPv4 の場合、65,535 バイトのパケットにはヘッダー情報も含まれるため、65,507 バイトしか保持できないことを意味します)、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

$
于 2016-11-01T17:54:37.883 に答える
0

への呼び出しで宛先アドレスまたはポートを変更する必要がありますsendto

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

Qt アプリケーションはどのアドレスとポートにバインドしますか?

于 2016-11-01T17:46:14.407 に答える