Script hangs when receiving data from socket - python

This is my Python script to receive data from client:
import time
import socket
HOST = ''
PORT = 8888
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created')
try:
s.bind((HOST, PORT))
except socket.error as socketError:
print('socket binding failed, ', socketError)
print('Exiting...')
sys.exit(0)
print('Socket binding complete')
s.listen(1)
print('Socket listening for connection...')
conn, addr = s.accept()
print('connected to ', addr[0])
bfr = b''
try:
while True:
while True:
temp = conn.recv(1024)
print('temp is ',temp.decode('utf-8'))
print('buffer value ', bfr.decode('utf8'))
if not temp:
break
bfr += temp;
data = bfr.decode('utf-8')
bfr = b''
print('value received,', data)
if data == 'Connection-Ready to receive commands':
print('')
#other conditions
except Exception as loopException:
print("Exception occurred in loop, exiting...")
finally:
s.close()
The script hangs up after printing
connected to 192.168.4.197
and is not accepting any commands from client. if the client disconnects, all the send commands are printed.
Why is it behaving like this?
Update 1
Tried removing the inner while and added a time.sleep(.10) and the script is not hanging up but only the first command is printing as is and the rest is printing with a linebreak after the first character like, if I send 10, it will print 1 first and 0 in another line. All I want is to get the commands as it is sent from the client, every command is single word.

Perhaps try sendall to make sure the data is sent in its entirety from the client?

Related

How to detect Socket/connection is closed abruptly in Python 3.6

How can I check if the client disconnects abruptly in Python 3.6. Here is my code,
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created')
try:
s.bind((HOST, PORT))
print('Socket binding complete')
except socket.error as socketError:
print('socket binding failed, ', socketError)
s.listen(1)
print('Socket listening for connection...')
conn, addr = s.accept()
conn.setblocking(0)
print('connected to ', addr[0])
try:
while True:
temp = conn.recv(1024)
if not temp:
break
data = int.from_bytes(temp, byteorder='big', signed=True)
print('value received,', temp)
print('converted value = ', data)
except Exception as loopException:
print("Exception occurred in loop, exiting...", loopException)
finally:
conn.close()
s.close()
This is working if the client disconnects normally, It is properly closing the connection. How can I check if the client disconnects abruptly?
You can at the beginning try to send to the client a packet and with it you can see if you are connected to the client or not
while True:
try:
string = "Are you up?"
s.send(string.encode())
except:
print("Can't seem to be connected with the client")
# here you can process the expection
# rest of the code
And in your case, you are already using non blocking socket conn.setblocking(0), so even if the client end the session and you don't receive any data temp, variable will contains nothing, and you will break from the loop (That if the client is if the client send data at every loop)
Or you can also set a timeout for response from the client
s.settimeout(30) # wait for the response of the client 30 seconds max
and in the recv line you can do:
try:
temp = conn.recv(1024)
except socket.timeout:
print('Client is not sending anything')

What does closing the socket do in the following code

I'm learning the sockets python module and I'm looking at the following tutorial code:
'''
Simple socket server using threads
'''
import socket
import sys
from thread import *
HOST = '' # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print 'Socket created'
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
#Function for handling connections. This will be used to create threads
def clientthread(conn):
#Sending message to connected client
conn.send('Welcome to the server. Type something and hit enter\n') #send only takes string
#infinite loop so that function do not terminate and thread do not end.
while True:
#Receiving from client
data = conn.recv(1024)
reply = 'OK...' + data
if not data:
break
conn.sendall(reply)
#came out of loop
conn.close()
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
#start new thread takes 1st argument as a function name to be run, second is the tuple of arguments to the function.
start_new_thread(clientthread ,(conn,))
s.close()
I'm stuck on the final line, s.close(). I don't understand what this does since the code seems to be stuck in an infinite loop right above, which is never broken. Am I missing something or is s.close() totally extraneous in this instance?

Python thread in socket chat application won't start

I'm new to python, and I'm trying to write a simple chat application, featuring a server which runs a thread that accepts from and transmits messages to connected clients, and a client which runs two threads that send messages to and accept messages from the server respectively. Here's the code
Server:
import socket
import sys
import thread
def receiveAndDeliverMessage(conn):
while True:
data = conn.recv(1040)
if not data: break
print(data)
conn.send(data)
conn.close
HOST = '' # Localhost
PORT = 8888 # Arbitrary non-privileged port
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #Create a TCP/IP socket
print 'Socket created'
#Bind socket to local host and port
try:
sock.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
sock.listen(10)
print 'Socket now listening'
# Create threads for receiving a connection from client and receiving data from client
while True:
connection, address = sock.accept() #Accept method returns a tupule containing a new connection and the address of the connected client
print 'Connected with ' + address[0] + ':' + str(address[1])
try:
thread.start_new_thread(receiveAndDeliverMessage, (connection))
except:
print ("Error: unable to start thread")
sock.close()
Client:
#Socket client example in python
import socket #for sockets
import sys #for exit
import thread
def sendMessage():
count = 0
while (count < 3):
message = raw_input('Write message to send to server: ');
count = count + 1
print 'message '+str(count)+': '+(message)
try :
#Send the whole string
sock.sendall(message)
except socket.error:
#Send failed
print 'Send failed'
sys.exit()
print 'Message sent successfully to server'
def receiveMessage():
reply = sock.recv(1024)
print reply#Print the message received from server
#create an INET, STREAMing socket
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print 'Failed to create socket'
sys.exit()
print 'Socket Created'
serverHost = 'localhost'
serverPort = 8888
try:
remote_ip = socket.gethostbyname(serverHost)
except socket.gaierror:
#could not resolve
print 'Hostname could not be resolved. Exiting'
sys.exit()
#Connect to remote server
sock.connect((remote_ip , serverPort))
print 'Socket Connected to ' + serverHost + ' on ip ' + remote_ip
try:
thread.start_new_thread(receiveMessage, ())
except:
print ("Error: unable to start receive message thread")
try:
thread.start_new_thread(sendMessage, ())
except:
print ("Error: unable to start send message thread")
sock.close()#Close socket to send eof to server
Now every time a client is opened, instead of the thread which runs receiveAndDelivermessage function running on the server, the exception gets thrown. So I get the "Error: unable to start thread". I don't understand why the exception gets thrown. Maybe I haven't yet quite grasped how threads work. Any help greatly appreciated. Also each time a client is opened, it gets terminated immediately, after the connection to server is established.
You swallow the original exception and print out a custom message so it's hard to determine what's causing the issue. So I am going to provide some tips around debugging the issue.
try:
thread.start_new_thread(receiveAndDeliverMessage, (connection))
except:
print ("Error: unable to start thread")
You are catching all types of exception in one except block which is quite bad. Even if you do so, try to find the message -
except Exception as ex:
print(ex)
Or you can also get the full traceback instead of just printing the exception:
import traceback
tb = traceback.format_ex(ex)

python3 - broken pipe error when using socket.send()

I am programming a client-server instant message program. I created a similar program in Python 2, and am trying to program it in Python 3. The problem is when the server takes the message and tries to send it to the other client, it gives me "[Errno 32] Broken Pipe" and exits.
I have done some research, and found that this occurs when the client disconnects, so I did some more testing but could not find when the client disconnects. (I am using Ubuntu 14.04 and Python 3.4)
Here is the server code:
import socket, select, sys
def broadcast(sock, messaged):
for socket in connection_list:
if socket != s and socket != sock:
# Here is where it gives me the broken pipe error
try:
s.send(messaged.encode("utf-8"))
except BrokenPipeError as e:
print(e)
sys.exit()
connection_list = []
host = ''
port = 5558
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host,port))
s.listen(5)
connection_list.append(s)
read_sockets,write_sockets,error_sockets = select.select(connection_list,[],[])
while True:
for sock in read_sockets:
if sock == s:
conn, addr = s.accept()
connection_list.append(conn)
client = "Client (%s,%s) connected" % addr
print(client)
broadcast(sock,client)
else:
try:
data = sock.recv(2048)
decodeddata = data.decode("utf-8")
if data:
broadcast(sock, decodeddata)
except:
offline = "Client " + addr + "is offline"
broadcast(sock, offline)
print(offline)
connection_list.remove(sock)
sock.close()
continue
And the client code:
import socket, select, string, sys, time
def prompt(data) :
print("<You> " + data)
def Person(data) :
print("<Receiver> " + data)
if __name__ == "__main__":
host = "localhost"
port = 5558
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(2)
try:
s.connect((host,port))
except:
print('Unable to connect')
sys.exit()
print('Connected.')
socket_list = [s]
read_sockets,write_sockets,error_sockets = select.select(socket_list,[],[])
while 1:
for sock in read_sockets:
if sock == s:
try:
time.sleep(1)
data = sock.recv(1024)
Person(data.decode("utf-8"))
except:
msg = input("Send a message: ")
try:
s.send(str.encode(msg))
except:
print("Server is offline")
sys.exit()
else:
print("Server is offline")
sys.exit()
There are two problems that you have to fix to make this work.
First, on both the client side and the server side, you have to put the select inside the loop, not outside. Otherwise, if there was something to read before you got to the loop, you'll recv over and over, and if there wasn't, you'll never recv. Once you fix this, you can get rid of the time.sleep(1). (You should never need a sleep to solve a problem like this; at best it masks the problem, and usually introduces new ones.)
Meanwhile, on the server side, inside broadcast, you're doing s.send. But s is your listener socket, not a connected client socket. You want socket.send here, because socket is each socket in connection_list.
There are a number of unrelated problems in your code as well. For example:
I'm not sure what the except: in the client is supposed to be catching. What it mainly seems to catch is that, about 50% of the time, hitting ^C to end the program triggers the send prompt. But of course, like any bare except:, it also masks any other problems with your code.
There's no way to send any data back and forth other than the "connected" message except for that except: clause.
addr is a tuple of host and port, so when someone goes offline, the server raises a TypeError from trying to format the offline message.
addr is always the last client who connected, not the one who's disconnecting.
You're not setting your sockets to nonblocking mode.
You're not checking for EOF on the recv. This means that you don't actually detect that a client has gone offline until you get an error. Which normally happens only after you try to send them a message (e.g., because someone else has connected or disconnected).

python recv never throws an error

This is the sample socket at server side (taken from some website):
import socket
import sys
HOST = '' # Symbolic name, meaning all available interfaces
PORT = 10001 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
print 'Socket created'
#Bind socket to local host and port
try:
s.bind((HOST, PORT))
except socket.error as msg:
print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
print 'Socket bind complete'
#Start listening on socket
s.listen(10)
print 'Socket now listening'
#now keep talking with the client
while 1:
#wait to accept a connection - blocking call
conn, addr = s.accept()
print 'Connected with ' + addr[0] + ':' + str(addr[1])
conn.send("Test Messag")
s.close()
This is the code at client side:
import socket
s=socket.socket()
s.connect((ipaddress,port))
s.setblocking(1)
import time
counter = 0
while True:
print counter
chunk = s.recv(11,socket.MSG_WAITALL)
if not chunk:
raise Exception('Socket error')
print chunk
time.sleep(1)
counter += 1
The server side code runs on an amazon ec2 instance (based on the amazon linux ami)
When I terminate the instance I would expect that the recv method on the socket throws an error, but it does not. Whatever I do, it never throws an error. When I run the server side code in an ipython notebook and restart the kernel, the recv method unlocks and keeps returning empty strings (according to When does socket.recv() raise an exception? this should be in the case of a clean shutdown), but no error is thrown.
What could be the cause of this, I really need to have it throw an exception so I can notify the rest of my code that the server went down in order to start a new one.
When I terminate the instance I would expect that the recv method on the socket throws an error ...
When the server terminates it will do a clean shutdown of the socket, so you will get no exception on the client side. To get what you want you would have to implement some kind of shutdown message inside your application. Then you can distinguish a proper shutdown (with an explicit shutdown message) from just a socket close.
You are making only one tcp connection. You have to make multiple request.
import socket
import time
counter = 0
while True:
print counter
s=socket.socket()
try:
s.connect((ipaddress,port))
s.setblocking(1)
chunk = s.recv(11,socket.MSG_WAITALL)
except Exception as e:
print e
break
print chunk
time.sleep(1)
counter += 1

Categories