Как прервать цикл while, если данные не принимаются, а длина данных неизвестна в python [TCP] - PullRequest
0 голосов
/ 04 сентября 2018

Я новичок в программировании на python и сокетах. Я пытаюсь отправить данные клиенту, а длина данных неизвестна. После получения всех данных на стороне клиента программа не завершает работу из-за цикла while (см. Код ниже). Я также использую команду (если не message: break), но она также не работает. Второй - проблема потери пакетов. Когда я не даю время. Sleep () на стороне отправителя затем получатель пропускает некоторый пакет (не получает все пакеты на стороне получателя, куда отправитель отправляет все пакеты). Как я могу выйти из цикла while без команды sys.exit? и .... Как я могу справиться со вторым вопросом без использования функции time.sleep. Это заметно, если кто-нибудь может мне помочь. Спасибо

[Узел приемника]

import socket
import os,sys


def frame_reception_function ():
    while True:
        PORT = 123
        s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
        s.bind(('',PORT))
        s.listen()
        conn,address=s.accept()
        message=conn.recv(4096).decode()
        print (message)
        conn.close()
frame_reception_function()

[Узел отправителя]

import os,sys
import socket
import time


MyNeighborSet_ip= ['192.168.1.2']


Data_transfer_listt = [['192.168.1.1', '192.168.1.2'], ['192.168.1.2', '192.168.1.3'], ['192.168.1.2', '192.168.1.4'], ['192.168.1.4', '192.168.1.5'], ['192.168.1.4', '192.168.1.6']]



def sending_Neighobr_ip_list():    
    #nn1=n1
    message='Neighbor_list_sending'
    #print (len(Data_transfer_listt))

    for i in range(len(Data_transfer_listt)):
        receiver_ip=Data_transfer_listt[i][0]
        receiver_node_list=Data_transfer_listt[i][1]
        T_message= message + ";" + receiver_ip + ";" + receiver_node_list
        T_message_bytes= bytes(T_message,'utf-8')
        PORT = 123
        print ("just after socket")
        for k in range (len(MyNeighborSet_ip)):
            s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
            s.connect((MyNeighborSet_ip[k],PORT))
            s.sendall (T_message_bytes) 
            s.close()
            time.sleep(0.01)


sending_Neighobr_ip_list()

1 Ответ

0 голосов
/ 04 сентября 2018

Это очень ресурсоемкое, чтобы продолжать открывать и закрывать сокет, я собираюсь убрать их из цикла while. Кроме того, я не могу вспомнить, является ли recv функцией блокировки или нет. Но это должно помочь вам правильно выйти из цикла while и решить вашу первую проблему.

Получатель:

def frame_reception_function ():
    data = []
    PORT = 123
    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    s.bind(('0.0.0.0',PORT))
    s.listen(1)
    conn,address=s.accept()  # accept an incoming connection using accept() method which will block until a new client connects
    while True:
        datachunk=conn.recv(1024) # reads data chunk from the socket in batches of 4086 bytes using method recv() until it returns an empty string
        if not datachunk:
            break  # no more data coming in, so break out of the while loop
        data.append(datachunk)  # add chunk to your already collected data

    conn.close()
    print(data)
    return

frame_reception_function()

Отправитель:

import os,sys
import socket
import time

MyNeighborSet_ip= [&ltTHE IP ADDRESS OF YOUR RECEIVER&gt]

Data_transfer_listt = [['192.168.1.1', '192.168.1.2'], ['192.168.1.2', '192.168.1.3'], ['192.168.1.2', '192.168.1.4'], ['192.168.1.4', '192.168.1.5'], ['192.168.1.4', '192.168.1.6']]

def sending_Neighobr_ip_list():
    #nn1=n1
    message='Neighbor_list_sending'
    #print (len(Data_transfer_listt))
    PORT = 123

    for k in range (len(MyNeighborSet_ip)): 
        s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((MyNeighborSet_ip[k],PORT))
        s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

        for i in range(len(Data_transfer_listt)):
            receiver_ip=Data_transfer_listt[i][0]
            receiver_node_list=Data_transfer_listt[i][1]
            T_message= message + ";" + receiver_ip + ";" + receiver_node_list
            T_message_bytes= bytes(T_message)

            print("sending message")
            s.sendall (T_message_bytes)

        s.close()

sending_Neighobr_ip_list()

Для THE IP ADDRESS OF YOUR RECEIVER я использовал свой локальный IP-адрес (192.168.x.x).

Это вывод на стороне приемника:

['Neighbor_list_sending;192.168.1.1;192.168.1.2', 'Neighbor_list_sending;192.168.1.2;192.168.1.3', 'Neighbor_list_sending;192.168.1.2;192.168.1.4', 'Neighbor_list_sending;192.168.1.4;192.168.1.5', 'Neighbor_list_sending;192.168.1.4;192.168.1.6']

Проблема на стороне отправителя, вы закрываете сокет каждую итерацию. Это заставляет приемник закрыть свое соединение тоже. Таким образом, отправитель успешно отправляет первое сообщение, а затем ошибки во втором соединении, поскольку получатель был закрыт и не ищет соединение. Вместо этого переключите порядок циклов. сначала установите соединение, затем отправьте свои сообщения, затем закройте соединение.

...