Forwarding and printing messages from multiple clients with sockets in python - python

I know there is a lot of post with titles similar to this one. Most of them have no answers or just answer how to respond to one client not multiple. Ive been bashing my head for sometime with this code. I know for sure that recieving connections and adding them to a list is working. My problem is when I try to print messages from the clients o screen. One client works fine, you can his messages on screen, the problem comes whith more than one client. When the second client connects you cant see his messages on the server side, after some messages from the first client, the messages sent from the second client appear. So I know for sure the messages are being recieved, the problem is with the printing.
server script:
import socket,sys
from threading import Thread
prevcon=0
buffsize=1024
connections=[]
addreses=[]
try:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
except socket.error as e:
print ("Failed to create a socket")
print (e)
host="192.168.0.103"#raw_input("Enter Target host here: ")
port=12345#raw_input("Enter Target port here: ")
try:
s.bind((host,int(port)))
except socket.error as e:
print ("Failed to Connect")
print (e)
s.listen(5)
s.setsockopt( socket.SOL_SOCKET,
socket.SO_REUSEADDR, 1 )
def listen_connections():
while True:
#print ("waiting for connection")
client_sock, addr = s.accept()
connections.append(client_sock)
addreses.append(addr)
print ("client connected from: ",addr)
def print_messages():
while True:
for i in range(0,len(connections)):
try:
data=connections[i].recv(buffsize)
except socket.error:
print ("User Disconnected from: ",connections[i])
connections[i].close()
del connections[i]
del addreses[i]
continue
print (data.decode("utf-8"))
print (connections)
#send_message(data,i)
s.close()
def send_message(data,pos):
for connection in connections:
if connection!=connections[pos]:
connection.send(data)
if __name__=="__main__":
thread1=Thread(target=listen_connections)
thread2=Thread(target=print_messages)
thread1.daemon=True
thread2.daemon=True
thread1.start()
thread2.start()
client script:
import socket,sys
from threading import Thread
try:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
except socket.error as e:
print ("Failed to create a socket")
print e
host="192.168.0.103"#raw_input("Enter Target host here: ")
port=12345#raw_input("Enter Target port here: ")
try:
s.connect((host,int(port)))
except socket.error as e:
print "Error Connecting"
print e
print ("Connected to host: %s and port: %s" %(host,port))
def leer():
while True:
data=s.recv(1024)
print data.decode("utf-8")
def send():
while True:
payload=raw_input("Enter here text to send: ")
s.send(payload)
if __name__=="__main__":
t1=Thread(target=leer)
t2=Thread(target=send)
t1.daemon=True
t2.daemon=True
t1.start()
t2.start()

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')

Script hangs when receiving data from socket

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?

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)

Python - Threading - Console o/p disapper

I am trying hands on with Socket Programming.Below is my server side code and I have not listed client side code here which is similar. As soon as the thread(in the try block) is called my console o/p disappears. Not sure how to handle this.Running it on DOS of Windows 7.Although I tried to read some existing discussion but found it was not very useful. Any help appreciated. Thanks..Ravi.
Code block:
import socket
import sys
import time
import thread
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 15000)
sock.bind(server_address)
sock.listen(1)
connection, client_address = sock.accept()
Servername = raw_input('Starting the chat(enter "QUIT" to discontinue), Please enter your name: ')
def Server_outgoing():
while True:
outgoing_message_server = raw_input()
if (outgoing_message_server == 'Quit' or outgoing_message_server == 'quit' or outgoing_message_server == 'QUIT'):
print "Server has decided to abort the chat - Bye bye"
break
print "######################################################################"
print >>sys.stderr, '"%s" : Printing outgoing message from Server "%s"' % (Servername, outgoing_message_server)
print "######################################################################"
connection.sendall(outgoing_message_server)
try:
thread.start_new_thread(Server_outgoing, ())
finally:
connection.close()
Ok guys..This worked..:
thread1 = Thread(target=Server_outgoing, args=())
thread1.start()
thread1.join()

Killing a thread with a socket in it (python)

I am pretty new at this.I am trying to build a server(chat server)
Sorry for presenting such a messing code.
There are alot of things that i am going to change about this code.
but as of now i just need help with one thing:
when i start let say more then one cleints on this ...and then just close the client i get this message:
Unhandled exception in thread started by
i have tryed to kill the thread as you can see in many places in this code. but i don't know what i am doing wrong ..
i am new at this.
any syggestions on what i should do ?
#encoding: utf-8
import socket, random, time, thread, errno, traceback
print socket.gethostname()
print "current machines IP address: "+socket.gethostbyname(socket.gethostname())
host ="10.0.0.1"# raw_input("IP: ")
# = socket.gethostbyname(socket.gethostname())
port = 12345
print host
conn_list =[None]*10
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((host, port))
sock.listen(10)
print "connected..\n\n\n\n"
def recv(conn):
while True:
try:
message = conn.recv(1024)
if "MESG" == message[1:5]:
message = message[6:].split(':')
name = str(conn)
conn_number = conn_list.index(conn)
conn_name = str(conn_number)
message = message[2]
reciever = message[0:1]
reciever = int(reciever)
for conn in conn_list:
if reciever == conn_list.index(conn):
conn.send(message)
print "Connection "+conn_name+" -----> "+str(reciever)+" :"+message+"\n"
#conn = findTheRightConnection(conn_list, conn_number)
break
else:
pass
except ValueError:
print "ValueError by %s" % (str(conn))
print conn.send("\nOpps you are not typing the correct connection number infront your message!")
except IOError:
bye(conn,conn_list)
print"Going to try to kill the thread here "
thread.quit()
thread.isAlive()
print "Still alive..."
except socket.error, v:
errorcode=v[0]
bye(conn,conn_list)
print"Going to try to kill the thread or here"
thread.quit()
thread.isAlive()
print "Still alive..."
except Exception, e:
traceback.print_exc()
finally:
thread.isAlive()
print"\nChanging the conn back to what it was... "
conn = findTheRightConnection(conn_list, conn_number)
def handle_connection(conn):
try:
recv(conn)
except socket.error, v:
errorcode=v[104]
bye(conn)
def bye(conn,conn_list):
i= 0
print "bye"
connectionName = str(conn_list.index(conn))
conn.close
conn_list = conn_list
print conn_list
for element in conn_list:
if element == conn:
conn_list[i] = None
break
i += i
print "Connection number "+connectionName+" is terminated"
print conn_list
return "Connection Terminated"
def welcome(conn,conn_list):
i = 0
for element in conn_list:
if element == None:
conn_list[i] = conn
print "Connection added in the conn_list on the slot %d" % (i)
print conn_list
return conn_list
else:
i = i+1
pass
print "The server if full! No more space left"
return conn_list
def findTheRightConnection(conn_list, number):
for conn in conn_list:
if number == conn_list.index(conn):
return conn
else:
pass
print "\nSomthing went wrong while trying to find the right connection in the method findTheRightConnection()"
return
while True:
conn, addr = sock.accept()
conn_list = welcome(conn,conn_list)
print "Got connection from : "+str(addr[0])+" by connection number: "+str(conn_list.index(conn))+"\n\n\n\n"
msg = "Welcome to the server!"
conn.send(":INFO:"+str(int(time.time()))+":"+str(len(msg))+":"+msg)
thread.start_new_thread(handle_connection, (conn,))
If you are still having trouble creating a instant messaging program in Python, you might be interested in this answer to another question.
Simple_Server.py is a minimal server implementation. A far more complex server with a variety of features can be provided on request. The complex server supports authentication, friends, private messaging, channels, filters, math evaluation, and admin controls.
MultichatClient.py is a port of a Java program written by a teacher from a networking class. The program must be run from the command line, and it must be given the server as an argument. You can use either the server's name on the network or its IP address.
Simple_Client.pyw is a more complicated client that does not require being started from the command line. When it starts, it will ask for server's name and try connecting to it while showing a progress dialog. The program will automatically try logging any errors to a file.
affinity.py is required for threadbox.py to run. (runs code on a specific thread regardless of origin)
threadbox.py is required for safetkinter.py to run. (metaclass clones classes to run using affinity)
safetkinter.py is required for Simple_Client.pyw to run. (makes tkinter safe to use with threads)

Categories