I have problem developing app in python.
I need to send data from server to client without prompt, but all examples I've found on internet are echo servers.
Server should have has static IP (127.0.0.1) and save clients IP on first connection. I need to send data from server to client for example every 5 seconds (until timeout) without server waiting to be asked for that data. Of course client sends another data in its own routine.
Server script:
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()
and Client script:
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)
I would really appreciate every help.
Example in which server keeps connection and sends data every 5 seconds. At the same time server keeps connection and receives data in loop. But it blocks server and client and loops should work in separated threads
server:
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()
client
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")
EDIT: version with threading
. And with queue
to send message to thread and stop it
server - classic construction. It can work with many clients at the same time
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 - socket in thread so program can do other things
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()
It would need some try/except
(ie. to catch Cltr+C and stop threads) and code which stop threads.
BTW: some examples from other my answers furas/python-examples/socket (on GitHub)