Socket server running other code and sending updates to clients - python

This may have been already answered but did not find anything or dont know what to search for. I have a socket server threaded for multiple clients (code below) and want the server to run code (ie. check the status of something) and then send a message to the clients. How do I go about doing this?
To clarify, I need to learn how to add a asynchronous task to this code so it can do checking and send a message to the clients if it needs to
Example: while there are clients connected I want the server to continually check a log file and if it changes and if so I want it to send a message to the clients
Server.py(working code)
from socket import *
import thread
BUFF = 1024
HOST = '127.0.0.1'# must be input parameter #TODO
PORT = 9999 # must be input parameter #TODO
def response(key):
return 'Server response: ' + key
def handler(clientsock,addr):
while 1:
data = clientsock.recv(BUFF)
if not data: break
print repr(addr) + ' recv:' + repr(data)
clientsock.send(response(data))
print repr(addr) + ' sent:' + repr(response(data))
if "close" == data.rstrip(): break # type 'close' on client console to close connection from the server side
clientsock.close()
print addr, "- closed connection" #log on console
if __name__=='__main__':
ADDR = (HOST, PORT)
serversock = socket(AF_INET, SOCK_STREAM)
serversock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
serversock.bind(ADDR)
serversock.listen(5)
while 1:
print 'waiting for connection... listening on port', PORT
clientsock, addr = serversock.accept()
print '...connected from:', addr
thread.start_new_thread(handler, (clientsock, addr))

I have added below code server.py and this works for sending a status change message when log file changes.
import socket
import sys
import time
from thread import *
HOST = 'localhost' # Symbolic name meaning all available interfaces
PORT = 9999 # 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
data = conn.recv(1024)
#infinite loop so that function do not terminate and thread do not end.
while True:
logfile = open("serverlog.txt","r")
#Receiving from client
logfile.seek(0,2)
while True:
line = logfile.readline()
if not line:
time.sleep(0.1) # Sleep briefly
continue
reply = 'File Changed...Your Data' + 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()
To test it run this server.py in one command prompt and keep it open. something like this
> python server.py
Socket created
Socket bind complete
Socket now listening
And run a simple telnet from other cmd prompt to verify the connection
telnet localhost 9999
Replace localhost with IP. Type anything on these telnet connection and you should get response properly.
Also you can check on server.py cmd prompt for the connections made.
And as I mentioned, check this link.

Related

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?

need to add timer thread in tcp server

I want to make tcp server bi-directional.
i want to add a timer thread and send data after every 10 sec to all clients.
My code is as follow
import socket
import sys
from thread import *
HOST = '192.168.137.130' # 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)
print data
print 'rcv data:'
#reply = 'OK...' + data
if not data:
break
conn.sendall('hello')
#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 have tried adding some code in while loop but couldn't achieve it as loops are only active whenever there is a new connection or when the client sends data to the server.

Trying to create messenger application python

Trying to Create Messenger Application within python (cross internet). So far I have successfully been able to send a message to the receiver end and then ping the message back to the user that sent it. However, it does not send the message to all connected users. I think this is because if python is listening for user input the socket cannot receive any data (I might be wrong...).
Below is the client side code:
import socket
host = '**.***.***.***' # Public Ip Hidden
port = 5005 # The same port as used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((host, port))
b = input("Please enter your message.")
b = b.encode('utf-8')
s.sendall(b)
while True:
data = s.recv(1024)
print('Message Received:', repr(data))
Now below is the server side code:
import socket
import sys
import os
import thread
import threading
from thread import *
from threading import Thread
HOST = '' # Symbolic name meaning all available interfaces
PORT = 5005 # Arbitrary non-privileged port
BUFFER_SIZE = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client = ''
clients = set()
clients_lock = threading.Lock()
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):
#infinite loop so that function do not terminate and thread do not end.
with clients_lock:
clients.add(client)
while True:
#Receiving from client
data = conn.recv(1024)
if not data:
break
else:
print repr(data)
with clients_lock:
for c in clients:
for d in data:
conn.sendall(data)
print(data.decode("utf-8"))
#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(clientthread ,(conn,))
s.close()
Any Suggestions would be much appreciated.

Python socket server send remote commands

Right now, I'm trying to make a socket server in Python that takes input from a client, processes it, does whatever is need to be done, and then sends a message back to the client showing that it's done.
The problem I am having right now is that the system can't recognize a command that is sent by the client. I am currently using an if statement to compare strings. The data received is decoded into UTF-8. I don't see why the if statement can't compare them.
'''
Simple socket server using threads
'''
import socket
import sys
from thread import *
import cmd
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
databyte = conn.recv(1024)
reply = 'OK...' + data
data = databyte.decode('utf-8')
if data == 'light'
print 'light'
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()
Any help would be appreciated! Thank you in advance!

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