So can someone please tell me how to have an admin-client shutting down the Server (server.py) in a socket multiple clients architecture? I want admin-client to type "shutdown" in client side then server will be shutdown. and right after submit, the server will call a function that shows network load graph . a graph with the number of requests per time slot.
Server:
`
import socket, threading
class ClientThread(threading.Thread):
def __init__(self,clientAddress,clientsocket):
threading.Thread.__init__(self)
self.csocket = clientsocket
print ("New connection added: ", clientAddress)
def run(self):
print ("Connection from : ", clientAddress)
#self.csocket.send(bytes("Hi, This is from Server..",'utf-8'))
msg = ''
while True:
data = self.csocket.recv(2048)
msg = data.decode()
if msg=='bye':
break
print ("from client", msg)
self.csocket.send(bytes(msg,'UTF-8'))
print ("Client at ", clientAddress , " disconnected...")
LOCALHOST = "127.0.0.1"
PORT = 8080
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((LOCALHOST, PORT))
print("Server started")
print("Waiting for client request..")
while True:
server.listen(1)
clientsock, clientAddress = server.accept()
newthread = ClientThread(clientAddress, clientsock)
newthread.start()
Client:
import socket
SERVER = "127.0.0.1"
PORT = 8080
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect((SERVER, PORT))
client.sendall(bytes("This is from Client",'UTF-8'))
while True:
in_data = client.recv(1024)
print("From Server :" ,in_data.decode())
out_data = input()
client.sendall(bytes(out_data,'UTF-8'))
if out_data=='bye':
break
client.close()
`
I have tried
if message == "shutdown":
close()
exit(0)
but dont know how to apply it
I currently have this code
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip = socket.gethostbyname(socket.gethostname())
port = 1111
address=(ip,port)
server.bind(address)
server.listen(1)
print("Started listening on", ip, ":", port)
client.addr=server.accept()
while True:
data = client.recv(1024)
print("received",data, "from the client")
print("Processing data")
if(data=="Hello server"):
client.send("hello client")
print("Processing done")
elif(data=="disconnect"):
client.send("goodbye")
client.close()
break
else:
client.send("Invalid data")
print("invalid data")
However i get this error message: NameError: name 'client' is not defined.
But why?
Well, that is devoted to the fact that the function server.accept() return two values, the socket itself and the address. Therefore being accepted this way:
client, addr = server.accept()
would allow what you are trying to achieve.
from socket import socket, AF_INET, SOCK_STREAM
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(("localhost", 7777))
sock.listen(1)
while True:
try:
connection, address = sock.accept()
print("connected from " + address)
received_message = sock.recv(300)
if not received_message:
break
connection.sendall(b"hello")
except KeyBoardInterrupt:
connection.close()
so Im trying to wrap my head around sockets and have this pretty simple script
but for some reason I can't kill this script with a KeyboardInterrupt
how do I do kill the script with a KeyboardInterrupt that and why can't I kill it with a KeyboardInterrupt?
To break to get out the while loop. Without break, the loop will not end.
To be safe, check whether connection is set.
from socket import socket, AF_INET, SOCK_STREAM
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(("localhost", 7777))
sock.listen(1)
while True:
connection = None # <---
try:
connection, address = sock.accept()
print("connected from ", address)
received_message = connection.recv(300)
if not received_message:
break
connection.sendall(b"hello")
except KeyboardInterrupt:
if connection: # <---
connection.close()
break # <---
UPDATE
There was a typo: KeyBoardInterrupt should be KeyboardInterrupt.
sock.recv should be connection.recv.
Try to use timeout to make the program periodically "jumps out" from the accept waiting process to receive KeyboardInterrupt command.
Here is an example of socket server:
import socket
host = "127.0.0.1"
port = 23333
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((host,port))
sock.listen()
sock.settimeout(0.5)
print("> Listening {}:{} ...".format(host,port))
try:
while True:
try:
conn, addr = sock.accept()
data = conn.recv(1024)
if not data:
print("x Client disconnected!")
# break
else:
print("> Message from client: {}".format(data.decode()))
msg = "> Message from server".format(data.decode()).encode()
conn.sendall(msg)
except socket.timeout:
# print("Timeout")
pass
except KeyboardInterrupt:
pass
except KeyboardInterrupt:
print("Server closed with KeyboardInterrupt!")
sock.close()
Try adding a timeout to the socket, like so:
from socket import socket, AF_INET, SOCK_STREAM
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(("localhost", 7777))
sock.settimeout(1.0)
sock.listen(1)
while True:
try:
connection, address = sock.accept()
print("connected from " + address)
received_message = sock.recv(300)
if not received_message:
break
connection.sendall(b"hello")
except IOError as msg:
print(msg)
continue
except KeyboardInterrupt:
try:
if connection:
connection.close()
except: pass
break
sock.shutdown
sock.close()
I had this issue on Windows. Here's how I handle stopping the process:
try:
while self.running:
try:
c, addr = self.socket.accept()
print("Connection accepted from " + repr(addr[1]))
# do special stuff here...
print("sending...")
continue
except (SystemExit, KeyboardInterrupt):
print("Exiting....")
service.stop_service()
break
except Exception as ex:
print("======> Fatal Error....\n" + str(ex))
print(traceback.format_exc())
self.running = False
service.stop_service()
raise
except (SystemExit, KeyboardInterrupt):
print("Force Exiting....")
service.stop_service()
raise
def stop_service(self):
"""
properly kills the process: https://stackoverflow.com/a/16736227/4225229
"""
self.running = False
socket.socket(socket.AF_INET,
socket.SOCK_STREAM).connect((self.hostname, self.port))
self.socket.close()
Note that in order to trigger a KeyboardInterrupt exception, use:
Ctrl+Fn+PageUp(Pause/Break)
The CTRL+C event can be caught in a separate process and sent back to another thread running in the main process to kill the socket. Example below, tested successfully on Windows 10 with Python 3.5.4. Placed some comments and print statements around so you can see what's happening.
from multiprocessing import Pipe, Process
from socket import socket, AF_INET, SOCK_STREAM
from threading import Thread
import time
def detect_interrupt(conn):
try:
print("Listening for KeyboardInterrupt...")
while True:
time.sleep(1)
except KeyboardInterrupt:
print("Detected KeyboardInterrupt!")
print("Sending IPC...")
conn.send(True)
conn.close()
def listen_for_interrupt(conn, sock):
print("Listening for IPC...")
conn.recv()
print("Detected IPC!")
print("Closing sock...")
sock.close()
if __name__ == "__main__":
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(("localhost", 7777))
sock.listen(1)
# Crate a Pipe for interprocess communication
main_conn, detect_conn = Pipe()
# Create a thread in main process to listen on connection
listen_for_interrupt_thread = Thread(
target=listen_for_interrupt, args=(main_conn, sock), daemon=True)
listen_for_interrupt_thread.start()
# Create a separate process to detect the KeyboardInterrupt
detect_interrupt_process = Process(
target=detect_interrupt, args=(detect_conn,))
detect_interrupt_process.start()
connection = None
try:
while True:
print("Running socket accept()")
connection, address = sock.accept()
print("connected from " + address)
received_message = sock.recv(300)
if not received_message:
break
connection.sendall(b"hello")
except KeyboardInterrupt:
print("Handling KeyboardInterrupt")
sock.close()
if connection:
connection.close()
For windows users,
Above solutions which try to catch KeyBoard interrupts don't seem to work. I ended up setting a timeout on my socket.
Something like:
server_socket.settimeout(10)
Here an exception is raised after 10 seconds of inactivity (like not receiving anything for 10 secs)
If the far-end sends data rarely, you should set timeout for the connection as well.
In this case the connection will raise timeout Exception, when the KeyboardInterrupt can be checked.
from socket import socket, AF_INET, SOCK_STREAM
sock = socket(AF_INET, SOCK_STREAM)
sock.bind(("localhost", 7777))
sock.settimeout(1.0)
sock.listen(1)
while True:
try:
connection, address = sock.accept()
connection.settimeout(1.0)
print("connected from " + address)
received_message = sock.recv(300)
if not received_message:
break
connection.sendall(b"hello")
except socket.timeout:
continue
except IOError as msg:
print(msg)
continue
except KeyboardInterrupt:
try:
if connection:
connection.close()
except: pass
break
sock.shutdown
sock.close()
My script is very simple.
1.) Server listens for an HTTP connection
2.) Client establishes connection
3.) Server prints our the client's HTTP request data
When a client connects to the server and makes a browser request it triggers the Socket error "Bad File Descriptor".
I'm not sure why it does this. Can anyone help me out?
import socket
host = ''
port = 1000
def proxy(connection,client):
request = connection.recv(MAX_DATA_RECV)
print request
connection.close()
def main():
try:
# create a socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# associate the socket to host and port
s.bind((host, port))
# listenning
s.listen(BACKLOG)
print("Listening for connections")
except socket.error, (value, message):
if s:
s.close()
print "Could not open socket:", message
# get the connection from client
while 1:
try:
conn, client_addr = s.accept()
print("Received connection from " + str(client_addr))
proxy(conn,client_addr)
#thread.start_new_thread(proxy, (conn,client_addr))
if s:
s.close()
except socket.error, (value,message):
print value
print message
sys.exit(1)
main()
You are closing the server socket after first client. Don't do this.
while True:
try:
conn, client_addr = s.accept()
print("Received connection from " + str(client_addr))
proxy(conn,client_addr)
except socket.error, (value,message):
print value
print message
I am having a multi-client server which listens to multiple clients. Now if to one server 5 clients are connected and I want to close the connection between the server and just one client then how am I going to do that.
My server code is:
import socket
import sys
from thread import *
try:
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
except socket.error,msg:
print "Socket Creation Error"
sys.exit();
print 'Socket Created'
host = ''
port = 65532
try:
s.bind((host, port))
except socket.error,msg:
print "Bind Failed";
sys.exit()
print "Socket bind complete"
s.listen(10)
print "Socket now listening"
def clientthread(conn):
i=0
while True:
data = conn.recv(1024)
reply = 'OK...' + data
conn.send(reply)
print data
while True:
conn, addr = s.accept()
start_new_thread(clientthread,(conn,))
conn.close()
s.close()