Socket programming stuck waiting for a response from the server - python

For a class assignment I need to use the socket API to build a file transfer application. For this project there two connections with the client and server, one is called the control and is used to send error messages and the other is used to send data. My question is, on the client side how can I keep the control socket open and waiting for any possible error messages to be received from the server while not blocking the rest of the program from running?
Example code (removed some elements)
#Create the socket to bind to the server
clientSocket = socket(AF_INET,SOCK_STREAM)
clientSocket.connect((serverName,portNum))
clientSocket.send(sendCommand) # Send to the server in the control connection contains either the list or get command
(If command is valid server makes a data connection and waits for client to connect)
clientData = socket(AF_INET,SOCK_STREAM)
clientData.connect((serverName,dataport)) #Client connects
recCommand = clientData.recv(2000) #Receive the data from server if command is successful
badCommand = clientSocket.recv(2000) #But if there is an error then I need to skip the clientData.recv and catch the error message in bad Command

when there is an error, the data-socket should be closed by the server, so recv ends automatically.

Related

Python server get recv from all clients conncted and not just from the first one that conncted

The title explain everything. I made Java code that sends messgaes for the python server, but evry time, just the first message is sends because every time, java conneced again to server, and the server keeps waiting to next message from the first client that I send in the first time.
How can the server get message from all clients are connectd? and not just from one?
My python server:
server = socket.socket()
server.bind((socket.gethostname(), 4786))
server.listen(5)
(client, (ipNum, portNum)) = server.accept()
print("Client connected")
while True:
message = str(client.recv(64).decode()) # Check if client send message. I want to change it to check all clients
if(message != ""):
print("Client: " + message)
else:
time.sleep(0.1)
Summary
The server.accept() must be called inside the loop.
TLDR
The socket server returned from the call socket.socket() is a 'listening' socket. It is not used for any data transfer but just for listening incoming connections. When the server is willing to accept incoming connection then calls server.accept(). This call waits till a client connects. When a client connects the accept wakes up and returns a socket that represents a connection to one client. This socket is then used for data send and received and should be closed when the communication with this specific client is done.
When server wants to accept connection from another client it must call server.accept() again to wait for connection from another client and use the unique client socket for each connected client.
If it sufficient to handle client sequentially then you can just move the call accept onto the loop. Furthermore you should close the client socket when the communication with the client is done.
If multiple clients can be connected in parallel then slightly more complicated design is needed. You can start a new thread for each client after accepting the connection. The thread can call recv in a loop and terminates when the client disconnects. See Multi Threaded TCP server in Python for example.

python socket server is hanging after sending data

I made a python socket server recently that listens on port 9777 the server is suppose to accept connections and once it does will allow you to send information to the client. The client will then print out whatever it received. However, I found that after I sent some data the server would hang until i reinitialized a new connection. Is there a reason for this and if so how can I prevent it from happening
The code of the server is :
import socket
import sys
host='0.0.0.0'
port=9777
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind((host,port))
s.listen(10)
c,a=s.accept()
while True:
command=raw_input('[input>] ')
if 'data' in command:
c.send('continue')
data=c.recv(1024)
print data
else:
continue
the code will only send data if the word data is in the string. Here is the code for the client:
import socket
import sys
host='192.168.0.13'
port=9777
while True:
try:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((host,port))
except:
continue
while True:
d=s.recv(9999)
print d
s.send('received')
My goal is to setup a connection between server and client. I want the server to be able to accept input from a user in a while loop and send the input to the client. The client needs to be able to receive information and when it does it will send a response to the server. Then the user can continue sending data to the server until they decide to terminate the program. However the server keeps hanging after sending data once to the client. Can anyone tell me how I can prevent that?
I try this code in my computer it's work fine , maybe you need to change host='192.168.0.13' to host='localhost'
and host='0.0.0.0' to host='localhost'
look at this picture
and if this problem stay maybe your ip address is the same of other device in the network for that try to run this command ipconfig /renew

One way web socket communication?

I was reading about the Python websocket-client library and realized that, to receive data, we have to start a connection:
from websocket import create_connection
ws = create_connection("ws://echo.websocket.org/")
print "Received " + ws.recv() + "..."
What if I just need a one-way connection? Say a Python script is running on my laptop, and it periodically sends messages to a local web server.
To receive messages, the web server would have to start a connection, but starting a connection requires a URL to connect to. My Python script is not a web server, so it lacks a URL. How could the web server receive messages from the script?
I tried to let the server listen for clients to connect with it via
ws = websocket.WebSocket()
while 1:
print 'received "' + ws.recv()
However, I get an error.
in _recv
bytes = self.io_sock.recv(bufsize)
error: [Errno 107] Transport endpoint is not connected
That error output leads me to believe that the server needs to connect in order to receive.
If you would want one way connection to the server, you could just listen on plain socket or use UDP or use HTTP requests ore any other TCP protocol.

Implementing a remote shell server in python

I am writing a remote shell server in python.Here how it works.
1-The client connect to the server.
2-The server prompt the client to login.
2-After that the user can send a shell command to the sever.
3-The sever execute the command.
Here is a snippet of the server code that handle the coming requests
cmd=sock.recv(8192)
output = subprocess.Popen(cmd.split(),stdout=subprocess.PIPE).stdout.read()
sock.send(output)
My problem is that I want the server to handle multiple clients and I want every client to have a separate shell session.
edit:
I want the server to start a new instance of the shell whenever it receives a new connection from a client and keep that instance in memory until the connection closes.
You can implement it that for every connected client you server starts a thread, just for that client and handles his commands. Something like:
def client_handler(socket, address):
# receive client commands and do whatever is necessary
if __name__ == '__main__':
# Socket, Bind, Listen
while True:
# Wait for connection and accept
thread.start_new_thread(client_handler, (socket, address))

Send/receive infinite loop with SocketServer - Python - ConnectionAbortedError

I am trying to use socketserver to create a simple server to send images to a client with TCP.
First I send a catalogue to the client and then it responds with a request.
In the handle of my server, I have this loop :
class MainHandler(socketserver.BaseRequestHandler):
def handle(self):
while 1:
try:
# Sending the catalogue
# Using my methods to get my catalogue with a HTTP header
response = self.server.genHTTPRequest(self.server.init.catalogue)
self.request.sendall(response.encode())
# Response of the client
self.data = self.request.recv(1024).decode()
if self.data:
print("Data received : {}".format(self.data))
except:
print("transmission error")
break;
In the main I use this line to create my server (it's in an other file) :
mainServer = MainServer.MainServer((init.adresse, int(init.port)), MainServer.MainHandler)
When I launch this program, the client connect successfully and receive the catalogue but it sends back only some data and the program jump in the exception of the try/catch. Without the try/catch, I got this error :
self.data = self.request.recv(1024).decode()
ConnectionAbortedError: [WinError 10053] An established connection was aborted by the software in your host machine
I don't understand what is the problem, maybe a synchronization missing or may I need to use threads ?
Thank you for your help
(I am using python 3.3)
The problem would be because of sendall(response.encode()) and this self.request.recv(1024).decode() has been done in the same socket and it could lead to ConnectionAbortedError.
You need to read all the data from the socket before putting other data into the socket. Like flushing of data.

Categories

Resources