Threaded python socket server - python

I have a Multihtreaded Server with python that can handle clients request, but i have a problem with this.
In my Server Class I have a start function that start listening to clients like this:
class Server:
def __init__(self, clients={}):
self.clients = clients
self.ip = 'localhost'
self.port = ****
self.pattern = '(C\d)'
def start(self):
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.s.bind((self.ip, self.port))
self.s.listen(10)
while 1:
clientsock, addr = self.s.accept()
print ('Connected with ' + addr[0] + ':' + str(addr[1]))
_thread.start_new_thread(self.handler, (clientsock, addr))
def handler(self, clientsock, addr):
data = clientsock.recv(BUFF)
print ('Data : ' + repr(data))
data = data.decode("UTF-8")
result = re.match(self.pattern, data)
print (data)
if(result):
self.registerClient(clientsock, data)
if(data == "Exit"):
self.exitClient(clientsock)
def server_response(self, message, flag, err):
if(flag):
res = message.encode('utf-8')
return res
else:
res = message.encode('utf-8')+ "[ ".encode('utf-8')+err.encode('utf-8')+ " ]".encode('utf-8')
return res
def registerClient(self, clientsock, data):
if(data in self.clients):
err = "Error : Client Name Exist!"
clientsock.send(self.server_response('Reg#NOK#', 0, err))
clientsock.close()
sys.exit(1)
self.clients[clientsock] = data
clientsock.send(self.server_response('Reg#OK', 1, ''))
def exitClient(self, clientsock):
try:
f = self.clients.pop(clientsock)
clientsock.send(self.server_response('BYE#OK', 1, ''))
clientsock.close()
except KeyError:
err = "Error : Client Doesn't Connected To Server!"
clientsock.send(self.server_response('BYE#NOK#', 0, err))
clientsock.close()
sys.exit(1)
And this is my client Class:
class Client:
def __init__(self, name):
self.name = name
self.ip = '127.0.0.1'
self.next_client = None
self.s = ""
try:
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except:
print ('Reg#NOK#[ ' + msg[1] + ' ]')
sys.exit()
def register(self, server):
self.s.connect((server.ip, server.port))
message = self.name
try:
self.s.sendall(bytes(message, 'UTF-8'))
except (socket.error):
print ('Send Failed')
sys.exit()
reply = self.s.recv(4096)
print ("Respose From Server : " + reply.decode("utf-8") )
def exitFromServer(self, server):
message = "Exit".encode('utf-8')
try:
a = self.s.sendall(message)
except (socket.error):
print ('Send Failed')
sys.exit()
reply = self.s.recv(4096)
And this is the main file:
from server import *
from client import *
import _thread
a = Server()
_thread.start_new_thread(a.start, ())
b = Client("C1")
b.register(a)
b.exitFromServer(a)
As you can see when start function from Server class called there is no thread that can handle create Client , I mean when I use start function like this with out thread there is no way that program can go ahead in main file , I know I should use another thread here but where and how, I use Python 3.4, Thanks for helping me.
Edit
the Problem with start was Solved , Thanks from tdelaney,
but when I run this only the register function works and exitFromServer dont do anything can you tell me where is the problem.the program dosent do anything after execute register function and it seems that its wating for something.

This mean?
import threading
from server import *
from client import *
global a
a = Server()
def sServer():
global a
a.start()
def cClient():
global a
b = Client("C1")
b.register(a)
s = threading.Thread(name='server', target=sServer)
c = threading.Thread(name='client', target=cClient)
s.start()
c.start()

In Server Class I must add another while True loop after handler function cause it shuould do all client request till client has request:
def handler(self, clientsock, addr):
while 1:
data = clientsock.recv(BUFF)
print ('Data : ' + repr(data))
data = data.decode("UTF-8")
result = re.match(self.pattern, data)
if(result):
self.registerClient(clientsock, data)
if(data == "Exit"):
self.exitClient(clientsock)
break

Related

Chat server and chat client

This program has both the ChatServer class and ChatClient class in the same file, and should be called in the terminal by --name=server --port=8800 for the server and --name=client1 --port=8800 for the client. The problem comes from the client class not being able to complete a try:
When running the program with server name, it seems to work fine. When it runs with client name, I get the output Failed to connect to chat server # port 8800.
You can find where this except statement lies.
import select
import socket
import sys
import signal
import _pickle as cPickle
import struct
import argparse
SERVER_HOST = 'localhost'
CHAT_SERVER_NAME = 'server'
# Some utilities
def send(channel, *args):
buffer = cPickle.dumps(args)
value = socket.htonl(len(buffer))
size = struct.pack("L", value)
channel.send(size)
channel.send(buffer)
def receive(channel):
size = struct.calcsize("L")
size = channel.recv(size)
try:
size = socket.ntohl(struct.unpack("L", size)[0])
except struct.error as e:
return ''
buf = ""
while len(buf) < size:
buf = channel.recv(size - len(buf))
return cPickle.loads(buf)[0]
class ChatServer(object):
def __init__(self, port, backlog=5):
self.clients = 0
self.clientmap = {}
self.outputs = []
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Enable re-using socket address
self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.server.bind((SERVER_HOST, port))
print('Server listening to port: %s...' % port)
self.server.listen(backlog)
# Catch keyboard interrupts
signal.signal(signal.SIGINT, self.sighandler)
def sighandler(self, signum, frame):
# Close the server
print("Shutting down server...")
# Close existing client sockets
for output in self.outputs:
output.close()
self.server.close()
def get_client_name(self,client):
info = self.clientmap[client]
host, name = info[0][0], info[1]
return '#'.join((name, host))
def run(self):
inputs = [self.server, sys.stdin]
self.outputs = []
running = True
while running:
try:
readable, writeable, exceptional = select.select(inputs, self.outputs, [])
except select.error as e:
break
for sock in readable:
if sock == self.server:
# handle the server socket
client, address = self.server.accept()
print("Chat Server: got connection %d from %s" % (client.fileno(), address))
# Read the login name
cname = receive(client).split('NAME: ')[1]
# Compute client name ad send back
self.clients += 1
send(client, 'CLIENT: ' + str(address[0]))
inputs.append(client)
self.clientmap[client] = (address, cname)
# Send joining information to other clients
msg = "\n(Connected: New client (%d) from %s)" % (self.clients, self.get_client_name(client))
for output in self.outputs:
send(output, msg)
self.outputs.append(client)
elif sock == sys.stdin:
# Handle standard input
junk = sys.stdin.readline()
running = False
else:
# Handle all other sockets
try:
data = receive(sock)
if data:
# Send as new client's message..
msg = '\n[' + self.get_client_name(sock) + ']>>' + data
# Send data to all except ourself
for output in self.outputs:
if output != sock:
send(output, msg)
else:
print("Chat server: %d hung up" % sock.fileno())
self.clients -= 1
sock.close()
inputs.remove(sock)
self.outputs.remove(sock)
# Sending client leaving info to others
msg = "\n(Now hung up: Client from %s" % self.get_client_name(sock)
for output in self.outputs:
send(output, msg)
except socket.error as e:
# Remove
inputs.remove(sock)
self.outputs.remove(sock)
self.server.close()
class ChatClient(object):
def __init__(self, name, port, host=SERVER_HOST):
self.name = name
self.connected = False
self.host = host
self.port = port
# Initial Prompt
self.prompt = '[' + '#'.join((name, socket.gethostname().split('.')[0])) + ']> '
# Connect to server at port
try:
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.connect((host, self.port))
print("Now connected to chat server# port %d" % self.port)
self.connected = True
# Send by name...
send(self.sock, 'NAME: ' + self.name)
data = receive(self.sock)
# Contains client address, set it
addr = data.split('CLIENT: ')[1]
self.prompt = '[' + '#'.join((self.name, addr)) + ']>'
except socket.error as e:
print("Failed to connect to chat server # port %d" % self.port)
sys.exit(1)
def run(self):
while self.connected:
try:
sys.stdout.write(self.prompt)
sys.stdout.flush()
# Wait for input from stdin and socket
readable, writable, exceptional = select.select([0, self.sock], [], [])
for sock in readable:
if sock == 0:
data = sys.stdin.readline().strip()
if data:
send(self.sock, data)
elif sock == self.sock:
data = receive(self.sock)
if not data:
print('Client shutting down')
self.connected = False
break
else:
sys.stdout.write(data + '\n')
sys.stdout.flush()
except KeyboardInterrupt:
print("Client interrupted")
self.sock.close()
break
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Socket Server Example with Select')
parser.add_argument('--name', action="store", dest="name", required=True)
parser.add_argument('--port', action="store", dest="port", type=int, required=True)
given_args = parser.parse_args()
port = given_args.port
name = given_args.name
if name == CHAT_SERVER_NAME:
server = ChatServer(port)
server.run()
else:
client = ChatClient(name=name, port=port)
client.run()

Sockets Programming with Video Streaming with python

I have to make a project where i accept multiple client connections and I have to send screenshots of the screen of the client to the server and show it on the screen and if I have to be able to stream clients screen to the server. How do I go about this? I've been trying to make this for about 2 months now. I am stuck and don't know how to make it.
Any reply is greatly appreciated.
This is the server code I have so far.
import threading
import socket
from queue import Queue
NUMBER_OF_THREADS = 2
JOB_NUMBER = [1,2]
queue = Queue()
class MultiServer(object):
#Initialize Server Object with host, port, socket, all connections and all the IP addresses
def __init__(self):
self.host = ""
self.port = 8965
self.socket = None
self.all_connections = []
self.all_addresses = []
self.all_users = []
#Create Socket
def socket_create(self):
#If socket creation fails except the error and show to the User and exit the program
try:
self.socket = socket.socket()
except socket.error as msg:
print("Socket creation failed, error: " +str(msg))
sys.exit(1)
#Use socket.setsockopt to keep reusing the same port
self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
return
def socket_bind(self):
#Bind socket to port and wait for incoming connections
try:
self.socket.bind((self.host, self.port))
self.socket.listen(5)
#Is binding the socket fails show error to the user and try again in 5 seconds
except socket.error as msg:
print("Socket binding error: " + str(msg))
time.sleep(5)
self.socket_bind()
return
def accept_connections(self):
#Accept Connections from multiple clients and save to list
#Close all old connections to prevent errors
for c in self.all_connections:
c.close()
self.all_connections = []
self.all_addresses = []
while True:
try:
conn, address = self.socket.accept()
conn.setblocking(1)
client_hostname = conn.recv(1024).decode("utf-8")
address= address + (client_hostname,)
except Exception as ex:
print('Error accepting connections: %s' %str(ex))
# Inifinite Loop
continue
self.all_connections.append(conn)
self.all_addresses.append(address)
print('\nConnection has been estalished: {0} ({1})'.format(address[-1], address[0]))
return
def send_commands(self):
while True:
cmd = input("$:")
if cmd == "list":
self.list_connections()
def list_connections(self):
""" List all connections """
results = ''
for i, conn in enumerate(self.all_connections):
try:
conn.send(str.encode(' '))
conn.recv(20480)
except:
del self.all_connections[i]
del self.all_addresses[i]
continue
results += str(i) + ' ' + str(self.all_addresses[i][0]) + ' ' + str(
self.all_addresses[i][1]) + ' ' + str(self.all_addresses[i][2]) + '\n'
print('----- Clients -----' + '\n' + results)
return
def create_workers():
server = MultiServer()
for i in range(2):
t = threading.Thread(target=work, args=(server,))
t.daemon = True
t.start()
def work(server):
while True:
x = queue.get()
if x == 1:
server.socket_create()
server.socket_bind()
server.accept_connections()
if x == 2:
server.send_commands()
queue.task_done()
return
def create_jobs():
for x in JOB_NUMBER:
queue.put(x)
queue.join()
def main():
create_workers()
create_jobs()
if __name__ == '__main__':
main()
And this is the Client code I have so far
import socket
class Client(object):
def __init__(self):
self.serverHost = '127.0.0.1'
self.serverPort = 8965
self.socket = None
def socket_create(self):
""" Create a socket """
try:
self.socket = socket.socket()
except socket.error as e:
print("Socket creation error" + str(e))
return
return
def socket_connect(self):
""" Connect to a remote socket """
try:
self.socket.connect((self.serverHost, self.serverPort))
except socket.error as e:
print("Socket connection error: " + str(e))
time.sleep(5)
raise
try:
self.socket.send(str.encode(socket.gethostname()))
except socket.error as e:
print("Cannot send hostname to server: " + str(e))
raise
return
def recieve_requests(self):
""" Controle of de server nog actief is """
try:
self.socket.recv(10)
except Exception as ex:
print("Couldn't recieve Commands: " + str(ex))
return
while True:
data = self.socket.recv(20480).decode("utf-8")
print(data)
print("mislukt")
client = Client()
client.socket_create()
def main():
client = Client()
client.socket_create()
try:
client.socket_connect()
except Exception as ex:
print(f"Socket connection error: {ex}")
while True:
try:
client.recieve_requests()
except Exception as ex:
print(ex)

Python - socket server receives more data than I sent

I made an app to send to python socket the message "Oleft" when i tilt the phone but the result on console is like:
connection from('192.168.0.101', 33313)
b'Oleft'
b'OleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleft'
b'Oleft'
b'OrightOrightOrightOright'
b'OleftOleftOleftOleftOleftOrightOrightOrightOrightOrightOrightOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleft'
b'OleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleft'
b'OleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleft'
b'OleftOleftOleftOleftOleftOleftOleftOleftOleftOleftOleft'
b'OleftOleft'
It has no way to receive only an b'Oleft' ?
wgremote.py
import socket
class WGRemote:
def __init__(self):
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.host = socket.gethostname()
self.port = 10000
self.received = None
def connect(self):
global c, addr
self.sock.bind((self.host, self.port))
self.sock.listen(5)
c, addr = self.sock.accept()
print('connection from' + str(addr))
def setMode(self,mode):
sent = c.send(mode.encode("utf-8"))
def receive(self):
self.received = c.recv(1024)
return self.received
def close(self):
c.close
testApp.py
import socket
import sys
from wgremote import WGRemote
remote = WGRemote()
remote.connect()
remote.setMode('orient')
while True:
data = remote.receive()
print(data)
Because, You wrote print(data) in the while loop :)
while True:
data = remote.receive()
print(data)
If you want to receive only an b'Oleft you can make a filter :
count = 0
while True:
data = remote.receive()
if data == "b'Oleft":
if count < 1:
count = count + 1
print(data)
Or you must send the only an b'Oleft :)

Python sockets not sending multiple messages

I am trying to send multiple commands to a device using openocd. The problem is it receives my first command and then stops. It never receives the next one.
import socket
class App(object):
def connect(self):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('connecting to host')
sock.connect(('localhost',4444))
return sock
def send(self, command):
sock = self.connect()
recv_data = ""
data = True
print('sending: ' + command)
sock.sendall(command)
while data:
data = sock.recv(1024)
recv_data += data
print('received: ' + data)
sock.close()
return recv_data
def main():
test = App()
print test.send("targets")
print test.send("reset")
if __name__=='__main__':
main()

python socket.error: [Errno 9] Bad file descriptor

I wanted to make a server and a client with Python.
It was supposed to make multiple connections, one, where the server is sending something to the client, and one where the client is sending something to the server.
The first connection worked fine, but the second one crashed with the message:
socket.error: [Errno 9] Bad file descriptor
Here is the Server:
import socket
import errno
import pickle
def Main():
host = '188.174.233.99'
port = 66666
all_text = ['text1', 'text2', 'text3']
all_description = ['Test \n Description1\n', 'Test \n Description1\n', 'Test \n Description1\n']
all_images = ['unlock.png', 'unlock.png', 'unlock.png']
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
s.bind((host, port))
s.listen(1)
while True:
c, addr = s.accept()
c.setblocking(0)
print "Connection from: " + str(addr)
command = c.recv(1024)
if command == 'GIVEALL':
textstring = pickle.dumps([all_text, all_images, all_description])#verwandelt Liste in String
c.send(textstring)
else:
try:
new_event = pickle.loads(command)
print new_event
caption = new_event[0]
image = new_event[1]
describtion = new_event[2]
city = new_event[3]
except:
pass
try:
c.close()
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
except socket.error as e:
if e.errno != errno.ECONNRESET:
raise
pass
if __name__ == '__main__':
Main()
And here is the Client:
import socket
import pickle
from kivy.properties import StringProperty
from kivy.properties import NumericProperty
from kivy.properties import ListProperty
class Netclient(object):
def __init__(self):
self.s = socket.socket()
self.texte = []
self.current = 'All'
self.ip = '188.174.233.99'
self.port = 66666
def giveWid(self):
print 'give Widgets executed'
if self.current == 'All':
self.texte, self.images, self.description = self.sentHOT(self.ip, self.port)
return self.texte, self.images, self.description
def sentHOT(self, host, port):
self.s.connect((host, port))
self.s.send('GIVEALL')#sends command
recived_string = self.s.recv(1023)
more_text = pickle.loads(recived_string)#verwandelt string in liste
self.s.close()
print 'closed'
return more_text[0], more_text[1], more_text[2]
def add_event(self, caption, image, description, city='Pawonkow'):
new_event = [caption, image, description, city]
new_compact_event = pickle.dumps(new_event)
self.s.connect((self.ip, self.port))
self.s.send(new_compact_event)
self.s.close()
n = Netclient()
t, i, d = n.giveWid()
print t
n.add_event('new', 'new.png', 'ew event', 'Hanau')
The reason is that you are trying to reconnect a closed socket. You have to either create a new socket or reuse the old one as long as it's connected.
In method def sentHOT(...): comment the line self.s.close() and in method def add_event(...) comment the line self.s.connect((self.ip, self.port)) then should work. Further, please take a look at this tutorial, it helps you with socket programming.

Categories

Resources