Python TCP сервер отправляет данные без запроса - PullRequest
0 голосов
/ 24 февраля 2020

У меня проблема с разработкой приложения на python.

Мне нужно отправить данные с сервера на клиент без запроса, но все примеры, которые я нашел на inte rnet, являются эхо-серверами.

Сервер должен иметь IP-адрес c (127.0.0.1) и сохранять IP-адрес клиента при первом подключении. Мне нужно отправлять данные с сервера на клиент, например, каждые 5 секунд (до истечения времени ожидания), при этом сервер не ждет, пока эти данные будут запрошены Конечно, клиент отправляет другие данные в своей собственной программе.

Серверный скрипт:

import socket

TCP_IP = "127.0.0.1"
TCP_PORT = 5010
BUFFER_SIZE = 512
MESSAGE = 'Hi'

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))
while(1):
    s.listen()

    conn, addr = s.accept()
    print ('Connection address:', addr)
    while 1:
        data = conn.recv(BUFFER_SIZE)
        if not data: 
            break
        print ("received data: ", data.decode())
        print ("address: ", addr[0])
        conn.send(MESSAGE.encode())  # echo
    print("Closing connection")
    conn.close()

и Клиентский скрипт:

import socket
import sys
import logging
import time

HOST, PORT = "127.0.0.1", 5010
data = " ".join(sys.argv[1:])

for x in range(100):
    # Create a socket (SOCK_STREAM means a TCP socket)
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        # Connect to server and send data
        sock.connect_ex((HOST, PORT))
        sock.sendall(bytes(data + "\n", "utf-8"))

        # Receive data from the server and shut down
        received = str(sock.recv(1024), "utf-8")
sock.close()
logging.info("Socket closed")

print("Sent:     {}".format(data))
print("Received: {}".format(received))
print("Size: ", sys.getsizeof(received), "bytes")

time.sleep(5)

Я был бы очень признателен за любую помощь.

1 Ответ

0 голосов
/ 24 февраля 2020

Пример, в котором сервер сохраняет соединение и отправляет данные каждые 5 секунд. При этом сервер сохраняет соединение и получает данные в l oop. Но он блокирует сервер и клиент, и циклы должны работать в отдельных потоках

сервер:

import socket
import time
import datetime


TCP_IP = "127.0.0.1"
TCP_PORT = 5010
BUFFER_SIZE = 512
MESSAGE = 'Hi'

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))

s.listen() # it can be before loop

while True:

    conn, addr = s.accept()
    print ('Connection address:', addr)
    while True:
        data = conn.recv(BUFFER_SIZE)
        if not data: 
            break
        print ("received data: ", data.decode())
        print ("address: ", addr[0])
        conn.send(MESSAGE.encode())  # echo

        # send data every 5 seconds - it should run in separated thread   
        while True:
            time.sleep(5)
            conn.send(str(datetime.datetime.now()).encode())

    print("Closing connection")
    conn.close()

клиент

import socket
import sys
import logging
import time

HOST, PORT = "127.0.0.1", 5010
data = " ".join(sys.argv[1:])

for x in range(100):
    # Create a socket (SOCK_STREAM means a TCP socket)
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        # Connect to server and send data
        sock.connect_ex((HOST, PORT))
        sock.sendall(bytes(data + "\n", "utf-8"))

        # Receive data from the server and shut down
        received = str(sock.recv(1024), "utf-8")

        print("Sent:     {}".format(data))
        print("Received: {}".format(received))
        print("Size: ", sys.getsizeof(received), "bytes")

        # receive data periodically - it should run in thread
        while True:
            received = str(sock.recv(1024), "utf-8")
            print("Received: {}".format(received))


sock.close()
logging.info("Socket closed")

РЕДАКТИРОВАТЬ: версия с threading. И с помощью queue отправить сообщение в поток и остановить его

server - classi c construction. Он может работать со многими клиентами одновременно

import socket
import time
import datetime
import threading

# --- functions ---

def process_client(conn, addr):
    print('Connection address:', addr)

    data = conn.recv(BUFFER_SIZE)
    if not data: 
        return

    print("received data: ", data.decode())
    print("address: ", addr[0])
    conn.send(MESSAGE.encode())

    # send data every 5 seconds
    while True:
        time.sleep(5)
        conn.send( str(datetime.datetime.now()).encode() )

    conn.close()

# --- main ---

TCP_IP = "127.0.0.1"
TCP_PORT = 5011
BUFFER_SIZE = 512
MESSAGE = 'Hi'

#all_threads = []

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((TCP_IP, TCP_PORT))

s.listen() # it can be before loop

while True:
    print('wait for next client')
    conn, addr = s.accept()

    t = threading.Thread(target=process_client, args=(conn, addr))
    t.start()
    #all_threads.append(t)

#for t in all_threads: t.join()    
print("Closing connection")
s.close()

client - сокет в потоке, поэтому программа может выполнять другие действия

import socket
import sys
import logging
import time
import threading
import datetime
import queue

# --- functions ---

def receive_data(q):

    # Create a socket (SOCK_STREAM means a TCP socket)
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
        # Connect to server and send data
        sock.connect_ex((HOST, PORT))
        sock.sendall(bytes(data + "\n", "utf-8"))

        # Receive data from the server and shut down
        received = str(sock.recv(1024), "utf-8")

        print("Sent:     {}".format(data))
        print("Received: {}".format(received))
        print("Size: ", sys.getsizeof(received), "bytes")

        # receive data periodically - it should run in thread
        while True:
            received = str(sock.recv(1024), "utf-8")
            print("Received: {}".format(received))

            if not q.empty() and q.get() == 'stop':
                break 

    # sock.close() # doesn't need if you use `with ... as sock`
    print("Socket closed")

# --- main ---

HOST, PORT = "127.0.0.1", 5011
data = " ".join(sys.argv[1:])

q = queue.Queue()
t = threading.Thread(target=receive_data, args=(q,))
t.start()

# other code

#while True:
for x in range(10):
    print('    Local time:', datetime.datetime.now())
    time.sleep(1)

q.put("stop") # message to thread to stop it

#t.join()

Для этого потребуется некоторое try/except (ie ... чтобы поймать Cltr + C и остановить потоки) и код, который останавливает потоки.


Кстати: некоторые примеры из других моих ответов furas / python -examples / socket ( на GitHub)

...