How can python socket client receive without being blocked - python

A simple demo of socket programming in python:
server.py
import socket
host = '127.0.0.1'
port = 8000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
s.listen(1)
conn, addr = s.accept()
while True:
data = conn.recv(1024)
print 'Received:', data
if not data:
break
conn.sendall(data)
print 'Sent:', data
conn.close()
client.py
import socket
host = '127.0.0.1'
port = 8000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.sendall('Hel')
s.sendall('lo world!')
print 'Received:', s.recv(1024)
s.close()
Now code work well. However, the client may not know if server will always send back every time. I tried symmetric code of while-loop in server.py
client_2.py
import socket
host = '127.0.0.1'
port = 8000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
s.sendall('Hel')
s.sendall('lo world!')
while True:
data = s.recv(1024)
if not data:
break
print 'Received:', data
s.close()
This code will block at
data = s.recv(1024)
But in server.py, if no data received, it will be blank string, and break from while-loop
Why it does not work for client? How can I do for same functionality without using timeout?

You can set a socket to non-blocking operation via socket.setblocking(false), which is equivalent to socket.settimeout(0). Solving this "without using timeout" is impossible.

Related

TCP able to send only first message

I make client-sever app. It look like this:
client
import socket
host = '127.0.0.1'
port = 1338
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
while True:
st = input("Your message: ")
byt = st.encode()
s.send(byt)
server
import socket
host = ''
port = 1338
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
while True:
s.listen(5)
conn, addr = s.accept()
data = conn.recv(2000)
print(data.decode())
Problem is that only first message is display. How can I solve this problem?
The server receives data only once after accepting a connection from the client. In-order to receive continuously, you can have a while loop for receiving data from the client.
import socket
host = ''
port = 1338
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
while True:
s.listen(5)
conn, addr = s.accept()
condition = True
while condition:
data = conn.recv(2000)
if not data: break
print(data.decode())
So, the above code will receive data as long the user provides data. You can separate the data receiving part in a separate thread too.
As you have the client's connect outside the loop, you have to place the server's listen and accept also outside the loop, since the connection is to be established only once.

Why doesn't the socket display the result?

I try to print out this code and the command in Pycharm looks like as it was looping through the code and no result displayed, I said that because the terminal doesn't complete its task, and the dollar sign doesn't appear. I need to know if that code results in any output from it. this code is a copy of some tutorial hence it's not created by me.
import socket
HOST = socket.gethostbyname(socket.gethostname())
PORT = 5050
ADDR = (HOST, PORT)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(ADDR)
s.listen()
print('running')
conn, addr = s.accept()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(ADDR)
s.sendall(b'Hello, world')
data = s.recv(1024)
s.close()
print('Received', repr(data))
Also, I need to know what is the relationships between (WSGI, ASGI) and their relations with the socket in python.
The code following conn, addr = s.accept() never runs because s.accept is blocking. Move the client socket's code to a separate file and run it seperately.
Server code:
import socket
HOST = socket.gethostbyname(socket.gethostname())
PORT = 5050
ADDR = (HOST, PORT)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(ADDR)
s.listen()
print('running')
conn, addr = s.accept()
data = conn.recv(1024)
conn.close()
s.close()
print('Received', repr(data))
Client code:
import socket
HOST = socket.gethostbyname(socket.gethostname())
PORT = 5050
ADDR = (HOST, PORT)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(ADDR)
s.sendall(b'Hello, world')
s.close()

How to write a python echo server that doesn't disconnect after first echo?

I want to set up a simple echo server that just echoes back whatever the client sends to it. However, currently the server disconnects (the server socket closes) after it echoes back the first client message. I want to be able to "chat" continuously with the server, where the server just echoes back several consecutive messages I send without disconnecting; e.g.:
"Hi there!"
"Echoing: Hi there!"
"How are you?"
"Echoing: How are you?"
"Cheers!"
"Echoing: Cheers!"
etc.
Currently I have the following code:
server.py:
import socket
HOST = '127.0.0.1'
PORT = 5000
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
client.py:
import socket
HOST = '127.0.0.1'
PORT = 5000
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)
print('Echoing: ', repr(data))
The server, however, disconnects after it echoes back the first client message (probably because of the if not data: break statement).
P.S. I'd appreciate any additional explanations which might be necessary - this example has educational purposes, so I'm not (only) after getting the code running.
Thanks!
server.py:
import socket
HOST = '127.0.0.1'
PORT = 5000
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
while True:
data = conn.recv(1024)
if data.decode() == "bye":
break
conn.sendall(data)
conn, addr = s.accept()
I will show you the code I created then talk you through it:
Server:
import socket
HOST = '127.0.0.1'
PORT = 5000
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
while True:
data = conn.recv(1024)
conn.sendall(data)
For the server I removed:
if not data:
break
It simply wasn't working for me. If you know your message is going to be less than the 1024 bytes( which here it is) it's unnecessary. But if you want a longer message change that value to a bigger number to accommodate. So yes you were right in suspecting it was that line.
Client:
import socket
HOST = '127.0.0.1'
PORT = 5000
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
print("Connected")
while True:
print("Sending data")
s.sendall(b'Hello, world')
print("Recieving data")
data = s.recv(1024)
print('Echoing: ', repr(data))
For the client side I just added the send and receive process into a loop.
Things to note:
This only works for me when run through the terminal, I don't know if you know how to do that so sorry if you do, here's a link explaining:
https://www.wikihow.com/Use-Windows-Command-Prompt-to-Run-a-Python-File
I assumed you use Windows.
You will need to follow the process for both your client.py programme and server.py programme. Make sure you run the server.py programme first.
This will cause an infinite loop of sending and receiving. Press Ctrl+C to terminate.
I hope this solves your problem and you can edit the code accordingly. Any further problems please do comment and I'll try to get back to you.
Maybe use sleep instead of break
if not data:
time.sleep(1)
continue
You have to import time module for this.

How to make socket server Python run forever

I have this code create a simple socket server Python.But it closes down each time client disconnect, how to I make it run forever?
import socket
HOST = ''
PORT = 8000
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024)
print(data)
conn.sendall('HelloClient'.encode())
if not data:
continue
If you want run forever just add a while True loop and accept the connections inside the loop.
See here for an example.

Sockets on Windows 7, can't connect

Trying to create my first client-server application, I came across an error. This code is exactly the same as in the documentation, but I have problems.
Server:
import socket
HOST = 'localhost'
PORT = 9090
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
while True:
data = conn.recv(1024)
if not data: break
print data
conn.close()
Client:
import socket
HOST = 'localhost'
PORT = 9090
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall('Hello, world')
s.close()
After execution, I don't see the message print Connected by, addr and print data in the server part.
I use Windows 7, Komodo Firewall (I tried to close the firewall, but it didn't solve the problem), Avast Antivirus, Python 2.7.
Very interesting, that there are no errors, but the output just doesn't work.
Also, my server application just freezes until the client connects to the server. Can this be solved just using threading?
Thanks in advance.
You need to accept() and print inside the loop. (or use two loops). I'm not very familiar with socket programming in Python but I'm guess it would look something like this. (completely untested!)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
while True:
conn, addr = s.accept()
print 'Connected by', addr
while True:
data = conn.recv(1024)
if not data:
break
print data
conn.close()
+1 to Cfreak. Basically what is happening with data is that it is getting assigned an empty string which causes the loop to break. So putting the print statement in the loop fixes the problem. Assuming you need to access that data after the loop terminates try something like
data = []
while True:
datum = conn.recv(1024)
data.append(datum)
if not datum: break
print " ".join(data)
Here is the code I am running and my computer, and it works
client
import socket
HOST = 'localhost'
PORT = 9090
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall('Hello, world')
s.close()
server
import socket
HOST = 'localhost'
PORT = 9090
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print 'Connected by', addr
data = []
while True:
datum = conn.recv(1024)
data.append(datum)
if not datum: break
print " ".join(data)
conn.close()
so I don't think it is a problem with your code... if you have a machine without a firewall/antivirus on it try the program on that machine.

Categories

Resources