TCP server gets stuck until a second client makes a request - python

This is the client
from socket import *
import sys
clientsocket = socket(AF_INET, SOCK_STREAM)
host = "localhost"
port = 10000
message = "Hello"
try:
clientsocket.connect((host,port))
except Exception as data:
print (Exception,":",data)
print ("try again.\r\n")
sys.exit(0)
clientsocket.send(message.encode())
print(message.encode())
response = clientsocket.recv(1024)
print (response)
clientsocket.close()
This is the server
from socket import *
import time
client_facing_port = 10000
router_client_socket = socket(AF_INET, SOCK_STREAM)
router_client_socket.bind(("localhost", client_facing_port))
print ('the router is up on port:',client_facing_port)
router_client_socket.listen(0);
while True:
print ('Ready to serve...')
connectionSocket, addr = router_client_socket.accept()
print(router_client_socket.accept())
try:
message = connectionSocket.recv(1024)
if len(message.split())>0:
print (message,'::',message.split()[0])
connectionSocket.send("Hello to you too".encode())
connectionSocket.send("\r\n".encode())
connectionSocket.close()
except IOError:
connectionSocket.send("something went wrong")
connectionSocket.close()
router_client_socket.close()
connectionSocket.close()
Very basic, I'm just trying to understand how sockets work in python.
Here's the problem, if I fire up the server the console prints
the router is up on port: 10000
Ready to serve...
and when I start the client its console prints
b'Hello'
basically the server gets stuck on connectionSocket, addr = router_client_socket.accept()
here's what I don't get, if I fire up a second client the console (of the second client) reads
ConnectionResetError: [WinError 10054] An existing connection was
forcibly closed by the remote host
which makes sense because the server is not multithread and can only handle one client at any given time since I used router_client_socket.listen(0), but the transaction between the first client and the server gets unstuck and completed! The first client receives the "hello to you too" message and prints it out.
What's causing this?
this is on python 3.9 using Spyder on Anaconda

Related

Python - A request to send or receive data was disallowed because the socket is not connected

I am creating a game in Pygame that requires a client-server part for the multiplayer.
First, I am checking if there are less than two connections. If this is the case, the client will be shown a screen that says 'waiting for connections'.
I have got the client to successfully send a '1' message to the server, which will respond with a '1' if the server is not full. Therefore, if the server does not respond with a 1, the server is full, and the client can continue.
However, I am getting this error mentioned in the title.
Server code:
import socket
import sys
import threading
from _thread import *
import time
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host=socket.gethostname()
ip=socket.gethostbyname(host)
port=8000
connections=[]
print('Your local ip address is',ip)
s.bind((host,port))
s.listen(2)
def threaded_client(connection):
while True:
data=connection.recv(2048) #anything we receive
if not data:
break
connection.close()
def checkconnected(connections):
noofconn=len(connections)
while True:
print('Waiting for a connection...')
connection,address=s.accept()
print(address,'has connected to server hosted at port',address[1])
connections.append(address)
data=connection.recv(1024)
received=[]
counter=0
for letter in data:
received.append(data[counter])
counter+=1
received=(chr(received[0]))
if received=='1':#handling initial connections
if len(connections)!=2:
s.sendall(b'1')
if not data:
break
start_new_thread(threaded_client,(connection,))
s.close()
The client code that calls it:
host=socket.gethostname()
ip=socket.gethostbyname(host)
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
address=address
port=8000
if address==ip:
ishost=True
else:
ishost=False
try:
s.connect((address,port))
connectionwaitingmenu()
connected=False
while connected==False:
s.sendall(b'1')
data=s.recv(1024)
received=[]
counter=0
for letter in data:
received.append(data[counter])
counter+=1
received=(chr(received[0]))
if received=='1':
connected=False
elif received!='1':
connected=True
classselection()
The error occurs on the s.sendall(b'1') line in the server code.
There are a few other problems in your code, but the cause of the error in the title is that you're using the wrong socket to send and receive data on the server side.
When a server accepts a new client (conn, addr = server.accept()) this returns a new socket, which represents the channel through which you communicate with the client. All further communication with this client happens by reading and writing on conn. You should not be calling recv() or sendall() on s, which is the server socket.
The code should look something like this:
# Assuming server is a bound/listening socket
conn, addr = server.accept()
# Send to client
conn.sendall(b'hello client')
# Receive from client
response = conn.recv(1024)
# NO
server.send(b'I am not connected')
this_wont_work = server.recv(1024)

using select() method for client/ server chat in Python

I am writing a client/ server program in Python where, once the client and server have successfully connected via a socket, they may exchange messages. Below is my server and client code. When compiled, the connection is established correctly and the messages are sent successfully, but one cannot send a second message until it has received a response from the other party.
For example:
Client sends: "Hello, server!"
Server sends: "I have received your message, client!"
Client sends: "great, here's another one"
Client sends: "and a second one!"
At this point, the server terminal window has received the message saying "great, here's another one", but must first reply to this message before receiving "and a second one!".
I think my issue is that I need to use the select() method, but do not understand how to do so. How can I fix this?
#The server code
HOST = ''
PORT = 9999
s = socket(AF_INET, SOCK_STREAM)
s.bind((HOST, PORT))
print("Now listening...")
s.listen(1) #only needs to receive one connection (the client)
conn, addr = s.accept() #accepts the connection
print("Connected by: ", addr) #prints the connection
i = True
while i is True:
data = conn.recv(1024) #receives data
print('Received:' , repr(data)) #prints the message from client
reply = raw_input() #server types a response
conn.sendall(reply) #server now sends response back to client
close()
below is the client code (client.py)
The client code
from socket import*
HOST = '192.168.41.1'
PORT = 9999
s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT))
while True:
message = raw_input() #client's message to the server
s.send(message) #sends message to the server
print("Waiting for response...")
reply = s.recv(1024) #receives message from server
print("New message: " + repr(reply)) #prints the message received
close()
Look at the following examples:
http://code.activestate.com/recipes/531824-chat-server-client-using-selectselect/
and
http://www.binarytides.com/code-chat-application-server-client-sockets-python/
also some similar answer here:
Python client side in chat
What you are missing is select on client side where its select if to handle input from server or from command line.
So in that case, you don't have to wait for server response and can send 2 calls one after another from the client.
Freely adapting the answers above to what you wished to accomplish.
(I didn't test it - so make sure to check it)
from socket import*
import sys
import select
HOST = '192.168.41.1'
PORT = 9999
s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT))
while True:
socket_list = [sys.stdin, s]
# Get the list sockets which are readable
read_sockets, write_sockets, error_sockets = select.select(
socket_list, [], [])
for sock in read_sockets:
#incoming message from remote server
if sock == s:
data = sock.recv(1024)
if not data:
print('\nDisconnected from server')
break
else:
#print data
sys.stdout.write(data)
# prints the message received
print("New message: " + repr(data))
prompt()
#user entered a message
else:
msg = sys.stdin.readline()
s.send(msg)
prompt()
s.close()
I would strongly suggest reading and familiarizing with this document and especially the non-blocking sockets part.
Your code now blocks when waiting for the data to arrive from the user. You want to instruct your program to wait for the data from the socket and at the same time allow user to type input.

Python Socket Scripting. What am i doing wrong?

My socket program hangs at clientsocket, address) = serversocket.accept() and doesn't spit our an error or anything.
I followed directions on https://docs.python.org/3/howto/sockets.html
I've been trying to figure it out for an hour now, but to no avail. I'm using python3 btw. What am i doing wrong? EDIT: My intedentation is all screwed up because I pasted it wrong, but other than that my code is as I have it in my file.
#import socket module
import socket
#creates an inet streaming socket.
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('socket created')
#binds socket to a public host, and a well known port
serversocket.bind(('127.0.0.1', 1024))
#print(socket.gethostname())# on desktop prints 'myname-PC')
#become a server socket
serversocket.listen(5) # listens for up to 5 requests
while True:
#accept connections from outside
#print('In while true loop') This works, but we never get to the next print statement. Why the hell is it catching at line 20?
(clientsocket, address) = serversocket.accept()
#clientsocket = serversocket.accept()
print('Ready to serve')
#now we do something with client socket...
try:
message = clientsocket.recv(1024)
filename = message.split()[1]
f = open(filename[1:])
outputdata = f.read()
#send an http header line
clientsocket.send('HTTP/1.1 200 OK\nContent-Type: text/html\n\n')
for i in range(0, len(outputdata)):
clientsocket.send(outputdata[i])
clientsocket.close()
except IOERROR:
clientsocket.send('HTTP/1.1 404 File not found!')
clientsocket.close()
If you haven't written a client script / program to connect to the socket and send it data, it's also going to hang on serversocket.accept() due to there being nothing to accept. But assuming you have...
while True:
#accept connections from outside
#print('In while true loop') This works, but we never get to the next print statement. Why the hell is it catching at line 20?
(clientsocket, address) = serversocket.accept()
#clientsocket = serversocket.accept()
It hangs because the loop never exits due to True always being True. In the example provided, once a connection is accepted they pretend that the server is threaded and the idea is to create a separate thread to begin reading and processing data received allowing the socket to continue to listen for more connections.
while True:
# accept connections from outside
(clientsocket, address) = serversocket.accept()
# now do something with the clientsocket
# in this case, we'll pretend this is a threaded server
ct = client_thread(clientsocket)
ct.run()

Python Socket errno 10054 only when client.py runs

There are some other posts about this issue but none did help me with mine.
I'm trying to build a total simple server - client relationship in python
server.py
#!/usr/bin/python
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(("127.0.0.1",8889))
s.listen(1)
try:
while True:
client, add = s.accept()
data = client.recv(1024)
if not data:
print 'No data'
print data
finally:
s.close()
client.py
#!/usr/bin/python
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1",8889))
try:
while True:
message = 'Foo'
s.send(message)
ans = s.recv(1024)
print ans
finally:
s.close()
I start by running the server first, but when I try to run the client I'm getting this Errno 10054 --> An existing connection was forcibly closed by the remote host
While request the browser with the ip and the related port, I receive some data.
I'm quiet new to networking, so please explain what might be obvious wrong in my code.
EDIT* Main issue is, that the client is somehow wrong, because it returns also an empty string on recv
Thank you in advance
Main issue is, that the client is somehow wrong, because it returns also an empty string on recv
The client isn't receiving anything from the server because the server is not sending anything.
On the server side, after print data, adding client.send(data) will send the string back to the client.
I am guessing:
The server accepts one socket and then does
client, add = s.accept()
data = client.recv(1024)
...
client, add = s.accept()
The client does this in the mean time:
s.send(message)
ans = s.recv(1024) # blocks until timeout
If now an other client connects to the server then client is replaced, the socket garbage collected and closed. s.recv(1024) will then tell that the connection is reset.
Have a look at import select or twisted (google around) to handle multiple connections at once.

Python, Connectin Refused 10061

I keep getting this error
[Errno 10061] No connection could be made because the target machine actively refused it.
I'm running Windows 7 64 bit, no virus or protection software, and python is allowed through my firewall (I've also tried turning my firewall completely off but same result). When I run the server and use telnet it connects just fine. When I try to connect to the server with the client it fails. Any suggestions as to what I could try to fix this? If you need more information just ask and I'll provide.
Client Code
import socket
import sys
def main():
host = ""
port = 8934
message = "Hello World!"
host = raw_input("Enter IP: ")
#Create Socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
print "Failed to create socket. Error code: %s Error Message: %s"%(str(msg[0]),msg[1])
sys.exit()
print "Socket created"
#Connec to Server
print host
print port
s.connect((host,port))
print "You are connected to %s with IP adress of %s"%(host,host)
#Send Data
try:
s.sendall(message)
except socket.error:
print "Failed to send."
#Receive Data
reply = s.recv(4096)
if __name__ == "__main__":
main()
Server Code
# !usr/bin/python
import socket
import sys
HOST = ""
PORT = 8934
def main():
#Setup socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error,msg:
print "Unable to create socket"
sys.exit()
print "Socket created."
#Bind to adress
try:
s.bind((HOST,PORT))
except socket.error,msg:
print "Bind failed. Closing..."
sys.exit()
print "Socket bound."
#Start listening
s.listen(10)
print "Socket Listening"
#Accept connection
conn, addr = s.accept()
print "Connected to %s:%s"%(addr[0],addr[1])
if __name__ == "__main__":
main()
Taking a guess at your indentation, and running your codeā€¦ it works just fine.* (As long as I type in 127.0.0.1 when it asks me for the IP.)
Of course the second time I run the client (if I haven't restarted the server) I get a connection-refused error. But that's just because you've coded a server that immediately quits as soon as it gets the first connection. So the second time you run the client, there is no server, so the OS rejects the connection.
You can always run the server again, which lets you run the client one more time. (Except that the server may get a 10048 error when it tries to bind the socket, because the OS is keeping it around for the previous owner. If you see that, look at SO_REUSEADDR in the docs.)
* By "works just fine" I mean that it connects, and prints out the following before quitting:
Socket created
127.0.0.1
8934
You are connected to 127.0.0.1 with IP adress of 127.0.0.1
Obviously it never sends anything to the server or receives anything back, because the server has no send or recv calls, or anything else.

Categories

Resources