How to wait for any socket to have data?
You can use select.select
for your problem:
sockets = [sock1, sock2, sock3]
while sockets:
rlist, _, _ = select.select(sockets, [], [])
for sock in rlist:
do_stuff(sock)
sockets.remove(sock)
How to use a socket without waiting in python
You can use sockets in non-blocking mode:
import pygame as pg
import socket
pg.init()
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("localhost", 55555)) # Connect to server
client.setblocking(False) # Prevent socket from waiting for input
W, H = 640, 480
FLAGS = 0
screen = pg.display.set_mode((W, H), FLAGS)
W, H = screen.get_size()
font = pg.font.SysFont("arial", 30)
text = ""
running = True
while running:
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
elif event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE:
running = False
try:
raw = client.recv(1024)
except BlockingIOError:
pass # No new data. Reuse old data
else:
text = raw.decode("utf-8") # New data has arrived. Use it
screen.fill((0, 0, 0))
img = font.render(text, True, (255, 255, 255))
r = img.get_rect(center=(W // 2, H // 2))
screen.blit(img, r)
pg.display.update()
This assumes a simple server script like this:
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("localhost", 55555))
server.listen()
while True:
client, address = server.accept()
print("Connected to", address)
while True:
line = input("> ")
try:
client.send(line.encode("utf-8"))
except ConnectionError as e:
print(e)
print("Disconnecting")
client.close()
break
It will display whatever line of text you entered on the server in the center of the pygame window.
If you want t he reverse situation, where the server has a pygame window open, you can use these pieces of code:
server:
import socket
import pygame as pg
pg.init()
W, H = 640, 480
FLAGS = 0
screen = pg.display.set_mode((W, H), FLAGS)
W, H = screen.get_size()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(("localhost", 55556))
server.listen(1)
server.setblocking(False)
client = None
font = pg.font.SysFont("arial", 30)
text = ""
clock = pg.time.Clock()
running = True
while running:
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
elif event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE:
running = False
elif event.type == pg.VIDEORESIZE:
screen = pg.display.set_mode(event.size, FLAGS)
W, H = screen.get_size()
# Logic
dt = clock.tick()
if client is None:
try:
client, address = server.accept()
except BlockingIOError:
pass
else:
try:
raw = client.recv(1024)
except BlockingIOError:
pass
else:
text = raw.decode("utf-8")
# Render
screen.fill((0, 0, 0))
img = font.render(text, True, (255, 255, 255))
r = img.get_rect(center=(W // 2, H // 2))
screen.blit(img, r)
pg.display.update()
pg.display.set_caption(f"FPS: {clock.get_fps():.2f}")
client
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(("localhost", 55556))
try:
while True:
line = input("> ")
try:
client.send(line.encode("utf-8"))
except ConnectionError as e:
print(e)
print("Disconnecting")
break
finally:
client.close()
If you want both to have pygames windows, I would suggest considering using multiple clients and one non-pygame server instead. But similar code should work anyway.
make client socket wait for server socket with Python
You can try something like this:
#!/usr/bin/env python
import pyaudio
import socket
import sys
import time
# Pyaudio Initialization
chunk = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 10240
p = pyaudio.PyAudio()
stream = p.open(format = FORMAT,
channels = CHANNELS,
rate = RATE,
input = True,
frames_per_buffer = chunk)
# Socket Initialization
host = ''
port = 50000
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connected = False
while not connected:
try:
s.connect((host,port))
connected = True
except Exception as e:
pass #Do nothing, just try again
# Main Functionality
while 1:
data = stream.read(chunk)
s.send(data)
s.recv(size)
As for your second question: This should work on remote connections as well, since you bind to all interfaces with host=''
Just make sure you portforward your router (only server needs to be port forwarded)
Python: fixed wait time for receiving socket data
The link with settimeout()
was right. It raises a Exception when timeout.
Set a timeout on blocking socket operations. The value argument can be
a nonnegative floating point number expressing seconds, or None. If a
non-zero value is given, subsequent socket operations will raise a
timeout exception if the timeout period value has elapsed before the
operation has completed. If zero is given, the socket is put in
non-blocking mode. If None is given, the socket is put in blocking
mode.
You need to put your code in a try
block, so that the Exception doesn't abort your program.
import socket.timeout as TimeoutException
# set timeout 5 second
clientsocket.settimeout(5)
for i in range(0,10):
sequence_number = i
start = time.time()
clientSocket.sendto("Ping " + str(i) + " " + str(start), server)
# Receive the client packet along with the address it is coming from
try:
message, address = clientSocket.recvfrom(1024)
except TimeoutException:
print("Timeout!!! Try again...")
continue
end = time.time()
if message != '':
print message
rtt = end - start
print "RTT = " + str(rtt)
Python socket wait for client connection
The socket.listen
function is to be called once, because it sets the size of the connection queue.
Another function called socket.accept
will block until connections are made. Modify your code like this:
mySocket = socket.socket()
mySocket.bind((host,port))
mySocket.listen(10)
while True:
client_socket, client_address = mySocket.accept() # blocking call
.... # do something with the connection
For more information, visit the docs.
Additionally, you'd want to pass the details of the client socket to the thread. The server socket isn't required. In effect, something like this:
def handle_client(client_socket, client_address):
.... # do something with client socket
client_socket.close()
...
while True:
client_socket, client_address = mySocket.accept()
T = threading.Thread(target=handle_client, args=(client_socket, client_address))
T.start()
You accept the connection in the main loop, then pass the client details to the thread for processing.
Related Topics
How to Copy/Repeat an Array N Times into a New Array
Unable to Install Psycopg2 (Pip Install Psycopg2)
Split a Large Json File into Multiple Smaller Files
Retrieve Top N in Each Group of a Dataframe in Pyspark
How to Change the File Name of an Uploaded File in Django
Counting How Many Times Each Vowel Appears
Best Practice to Run Multiple Spark Instance At a Time in Same Jvm
Import a File from a Subdirectory
Spark Add New Column With Value Form Previous Some Columns
How to Set Proxy Authentication (User & Password) Using Python + Selenium
How to Use and Print the Pandas Dataframe Name
Python - Remove Any Element from a List of Strings That Is a Substring of Another Element
Print a List of Space-Separated Elements
Inserting a Python Datetime.Datetime Object into MySQL
Flask Installed, But Modulenotfounderror: No Module Named 'Flask'