2016-11-01 4 views
1

텍스트 파일의 내용을 한 줄씩 끝없는 루프로 보내는 UDP 서버를 시뮬레이트해야합니다. 나는 아래의 코드를 작성했지만 다른 쪽 끝에서 난 아무것도받지 않습니다 (다른 쪽은 Qt는 코드는 내가 작동 확신) : 파이썬 UDP 서버가 텍스트 파일의 라인을 보냅니다.

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) 

내가 더 파이썬 프로입니다 않고 문제를 파악하지 못할 : (

+0

: 파일을 읽는 것은의 길을 그냥 끔찍한 ... –

+0

@ Jean-FrançoisFabre 옙 ... as sai d 파이썬 코드가 없으면, 작동하기 위해 빠르고 더러운 UDP 소켓이 필요합니다 : ( –

+1

누군가에게 당신은 IP와 포트가 필요합니다. '('localhost', 9763)'에 바인드하고 나중에'('localhost', 9763)에게 보내면 다른 프로그램으로 보내지 않습니다. 같은 포트에 – furas

답변

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) 행이 불필요한 경우 제거하십시오.


다른 것은이 파일을 읽는 코드 읽기가 매우 비효율적이고 어렵다는 것이다 (이것은 무슨 일이 일어나고 있는지 이해하는 데에 시간이 좀 걸렸습니다). 다음과 같이 시도하십시오.

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) 호출을 제거 할 수 있습니다.

+0

고마워요! 당신은 생명의 은인입니다 : D –

0

당신은 sendto에 전화에서 대상 주소 또는 포트를 변경해야합니다

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

하는 주소와 포트합니까 Qt는 응용 프로그램 바인딩

+0

, 9763 –

+0

@SaeidYazdani 그러면 호스트가 달라야합니다. 2 개의 다른 응용 프로그램은 같은'(호스트, 포트) 쌍에 바인드 할 수 없습니다. OS가 허용하지 않습니다. – freakish

1

삼촌 구글은 User Datagram Client and Server

사용자 데이터 그램 클라이언트 및 서버 사용자 데이터 그램 프로토콜 (UDP)는 TCP/IP에서 다르게 작동

함께했다. TCP가 스트림 지향 프로토콜 인 경우, 모든 데이터가 올바른 순서로 전송되도록 UDP는 메시지 지향 프로토콜입니다. UDP는 오래 지속되는 연결을 필요로하지 않으므로 UDP 소켓을 설정하는 것이 조금 더 간단합니다. 반면에 UDP 메시지는 단일 패킷 (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를 에코 클라이언트는 서버와 유사하지만 주소에 소켓을 연결하는 바인딩()를 사용하지 않습니다. sendto()를 사용하여 메시지를 서버로 직접 전달하고 recvfrom()을 사용하여 응답을 수신합니다.

$ 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 

및 클라이언트 출력은 다음과 같습니다 :

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_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 

$ 
관련 문제