How to display reply of the GET message on the broswer? - python

I got the assignment where I was needed to write a server program, more like a proxy server, where I send a GET request from the browser while running the proxy server. It should check it in the cache whether it exist or not then send back the reply (html documents) otherwise it ask the server the requested page and return it to the proxy server where it would be directed back to the client (browser).
I have done a awful lot of google search to find hints but haven't found one. If anyone can point me to the right direction or give some hint, I would be grateful.
Here is one example code I found but it cannot get a page and display it in the browser.
# import the required library
import socket, threading
class ClientThread(threading.Thread):
def __init__(self,ip,port, socket):
threading.Thread.__init__(self)
self.ip = ip
self.port = port
self.socket = socket
print "[+] New thread started for "+ip+":"+str(port)
# Entry point for thread
def run(self):
print "Connection from : "+ip+":"+str(port)
#clientsock.send("\nWelcome to the server\n\n")
self.socket.send("\nWelcome to the server\n\n")
data = "dummydata"
while len(data):
data = self.socket.recv(2048) #clientsock.recv(2048)
print "Client sent : "+data
self.socket.send("You sent me : "+data)
print "Client disconnected..."
host = "localhost"
port = 9999
# Create server socket object
tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Port reused immediately after the socket is closed
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# Bind the server socket to the port
tcpsock.bind((host,port))
threads = []
while True:
# Start listening to new connections
tcpsock.listen(4)
print "\nListening for incoming connections..."
(clientsock, (ip, port)) = tcpsock.accept()
# Create new thread
newthread = ClientThread(ip, port, clientsock)
# Start new thread
newthread.start()
threads.append(newthread)
# Wait for threads to terminate
for t in threads:
t.join()
I very new to python and I really need help here.

Related

How to correctly manage a maximum number of connected clients - Python Client Server TCP

I'm working on a tcp server and a tcp client application developed in Python 3.6.
Once connection has been established, the server sends data to the client and receive data from the client itself.
The server should accept a maximum number of clients. What i'd like is that when the maximum number of connected clients is reached, the server does not accept any other connections and the client is notified and aborted.
Here the server code:
class ThreadedServer(object):
def __init__(self, host, port, max_clients):
self.host = host
self.port = port
self.max_clients = max_clients
self.connected_clients = 0
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind((self.host, self.port))
def listen(self):
self.sock.listen(5)
while True:
if self.connected_clients >= self.max_clients:
print("Maximum number of clients reached")
continue
client, address = self.sock.accept()
# keep track connected clients
self.connected_clients += 1
# start a new thread to send data to the connected client
# start a new thread to receive data to the connected client
if __name__ == "__main__":
HOST = "xxx.xxx.xxx.xxx"
PORT = xxxx
MAX_CLIENTS = x
ThreadedServer(HOST, PORT, MAX_CLIENTS).listen()
The client code is the following:
class ThreadedClient(object):
def __init__(self, host, port):
self.host = host
self.port = port
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
def send(self):
self.sock.connect((self.host, self.port))
# start a new thread to receive data to the server
# start a new thread to send data to the server
if __name__ == "__main__":
HOST = "xxx.xxx.xxx.xxx"
PORT = xxxx
ThreadedClient(HOST, PORT).send()
Everything works fine until the maximum number of connected clients is reached.
When an "extra" client is launched, it does not (correctly) receive anything from the server but it starts to try to send data. Data are not received because the server did not accept the connection.
What I'd like is find a way to understand when the server did not accept the client connection before starting new threads in order to manage this scenario correctly.
You're calling client.close() before actually retrieving the client. This will mean that the last client that was accepted will still be in the client variable. This connection will be closed, not the new one.
def listen(self):
self.sock.listen(5)
while True:
client, address = self.sock.accept() # this line needs to be before the if
if self.connected_clients >= self.max_clients:
print("Maximum number of clients reached")
client.close()
continue
# keep track connected clients
self.connected_clients += 1
# start a new thread to send data to the connected client
# start a new thread to receive data to the connected client

Only one usage of each socket address (protocol/network address/port) is normally permitted,

I have a server that uses a thread to listen for new connections and then starts one thread for every client to serve him. Now, the server runs perfectly, but when a client connects it gives me the error in the title. I think because both client and server are trying to use the same port.
Here's the server code:
class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
def __init__(self, conne):
initialization
def handle(self):# "run"
does something
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
HOST = '' # Symbolic name meaning all available interfaces
PORT = 1000 # Arbitrary non-privileged port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(5)
n=1
while 1:
conn, addr = s.accept() # wait for a new connection. Get a new socket (conn) for each new connection
print 'Connected by', addr
server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler) #this line gives me the error
ip, port = server.server_address
server_thread = threading.Thread(target=server.serve_forever)
server_thread.setDaemon(True)
server_thread.setName('Client '+str(n))
server_thread.start() # Start the new thread
n+=1
server.shutdown()
server.server_close()
And here's the client:
import socket
HOST, PORT = "localhost", 1000
data = "0"
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
sock.connect((HOST, PORT))
sock.sendall(data)
received = sock.recv(1024)
finally:
sock.close()
print "Sent: {}".format(data)
print "Received: {}".format(received)
First you create server socket and bind it to port 1000. Then when client connects you receive a socket connected with client (conn, addr = s.accept()) that should be used to communicate with client but you completely ignore it. Instead you create another server that tried to bind again to port 1000. This results in "already used" error as expected.
I'd suggest you check this example of TcpServer threading and forking. Here a custom class derived from SocketServer.TCPServer is created initially (not a simple server socket as you do). It internally loops over accepting incoming client connections and for each connection calls specified SocketServer.BaseRequestHandler from a new thread or process (in case of forking) so you don't need to deal with them explicitly. Custom request handler just needs to, well, handle the request, potentially in a loop if communication with client is multi-step.
Be aware that thread/process per client approach doesn't scale well on large number of simultaneous client connections.

Multi threaded server send function

I got this multi threaded server code and it works but when I type something to send to the client its not sending it the send function only work if I send the data string
anyone knows what's the problem?
#!/usr/bin/env python
import socket, threading
class ClientThread(threading.Thread):
def __init__(self, ip, port, clientsocket):
threading.Thread.__init__(self)
self.ip = ip
self.port = port
self.csocket = clientsocket
print "[+] New thread started for "+ip+":"+str(port)
def run(self):
print "Connection from : "+ip+":"+str(port)
clientsock.send("Welcome to the server ")
data = "dummydata"
while len(data):
data = self.csocket.recv(2048)
print "Client(%s:%s) sent : %s"%(self.ip, str(self.port), data)
userInput = raw_input(">")
self.csocket.send(userInput)
print "Client at "+self.ip+" disconnected..."
host = "0.0.0.0"
port = 4444
tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpsock.bind((host, port))
while True:
tcpsock.listen(4)
print "nListening for incoming connections..."
(clientsock, (ip, port)) = tcpsock.accept()
#pass clientsock to the ClientThread thread object being created
newthread = ClientThread(ip, port, clientsock)
newthread.start()
Well, I can see at least one thing that will prevent this from working as intended:
def run(self):
print "Connection from : "+ip+":"+str(port)
clientsock.send("Welcome to the server ")
clientsock is undefined.
My suggestion is don't try to reinvent the wheel (unless you want to understand how the wheel works). There's already the built-in SocketServer but that is synchronous, meaning each request must be completed before the next request can be started.
There are already very easy to use implementations of asynchronous (non-blocking) TCP servers out there. If you want something that doesn't require you to learn a framework and just runs out-of-the-box, I suggest simpleTCP. Here's an example of an echo server:
from simpletcp.tcpserver import TCPServer
def echo(ip, queue, data):
queue.put(data)
server = TCPServer("localhost", 5000, echo)
server.run()
And here's an example of a client connecting to it:
from simpletcp.clientsocket import ClientSocket
s1 = ClientSocket("localhost", 5000)
response = s1.send("Hello, World!")

create multi-thread tcp server python 3

Hello I tried to make a simple server that accept multiple clients simultaneously I'm new to python and I have a difficult to understand it....I try to change my code in multi-thread applications but without positive result...here is the code:
import socket, threading
def message():
while 1:
data = connection.recv(1024)
if not data: break
#connection.sendall(b'-- Message Received --\n')
print(data.decode('utf-8'))
connection.close()
def connection():
address = input("Insert server ip")
port = 44444
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((address, port))
s.listen(1)
print("Server started! Waiting for connections...")
def accept connection():
connection, address = s.accept()
print('Client connected with address:', address)
t=thread.Threading(target=message,args=(connection))
t.run()
I know that there are many errors but I'm new in python sorry :(
The original non-threaded code is:
import socket
address = input("Insert server ip:")
port = 44444
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((address, port))
s.listen(1)
print("Server started! Waiting for connections...")
connection, address = s.accept()
print('Client connected with address:', address)
while 1:
data = connection.recv(1024)
if not data: break
#connection.sendall(b'-- Message Received --\n')
print(data.decode('utf-8'))
connection.close()
Your basic design is close, but you've got a whole lot of little problems making it hard to move forward.
First, you have a function name with a space in it, which isn't allowed. And you have an IndentationError because you didn't indent its contents.
Next, inside that accept_connection function, you're using threading wrong.
thread.Threading doesn't exist; you probably meant threading.Thread.
args has to be a sequence (tuple, list, etc.) of values. You probably expected (connection) to be a tuple of one value, but it's not; tuples are defined by commas, not parentheses, and what you have is just the value connection with superfluous parentheses around it. You wanted (connection,) here.
Also, calling run on a thread object just runs the thread's code in the current thread. You want to call start, which will start a new thread and call the run method on that thread.
Meanwhile, you're never actually calling this function anywhere, so of course it can't do anything. Think about where you want to call it. After creating the listener socket, you want to loop around accept, kicking off a new client thread for each accepted connection, right? So, you want to call it in a loop, either inside connection, or at the top level (in which case connection has to return s).
And finally, your accept_connection function can't access local variables from some other function; if you want it to use a socket named s, you have to pass it as a parameter.
So:
def connection():
address = input("Insert server ip")
port = 44444
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((address, port))
s.listen(1)
print("Server started! Waiting for connections...")
while True:
accept_connection(s)
def accept_connection(s):
connection, address = s.accept()
print('Client connected with address:', address)
t=thread.Threading(target=message, args=(connection,))
t.start()
As a side note, be careful with using sock.recv(1024) and assuming you're going to get the whole message that the other side sent with send(msg). You might get that, or you might get half the message, or the whole message plus half of another message the client sent later. Sockets are just streams of bytes, like files, not streams of separate messages; you need some kind of protocol to separate messages.
The simplest possible protocol is to send each message on its own line. Then you can just do socket.makefile() and for line in f:, just like you would for a real file. Of course this doesn't work if your messages can have newlines, but you can, e.g., backslash-escape them on one side and unescape them on the other.
This is a pretty old post but there's a nice way to do what you're talking about. Here's a link to an example I posted a little while back:
https://bitbucket.org/matthewwachter/tcp_threadedserver/src/master/
And the script:
from datetime import datetime
from json import loads, dumps
from pprint import pprint
import socket
from threading import Thread
class ThreadedServer(Thread):
def __init__(self, host, port, timeout=60, debug=False):
self.host = host
self.port = port
self.timeout = timeout
self.debug = debug
Thread.__init__(self)
# run by the Thread object
def run(self):
if self.debug:
print(datetime.now())
print('SERVER Starting...', '\n')
self.listen()
def listen(self):
# create an instance of socket
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
# bind the socket to its host and port
self.sock.bind((self.host, self.port))
if self.debug:
print(datetime.now())
print('SERVER Socket Bound', self.host, self.port, '\n')
# start listening for a client
self.sock.listen(5)
if self.debug:
print(datetime.now())
print('SERVER Listening...', '\n')
while True:
# get the client object and address
client, address = self.sock.accept()
# set a timeout
client.settimeout(self.timeout)
if self.debug:
print(datetime.now())
print('CLIENT Connected:', client, '\n')
# start a thread to listen to the client
Thread(target = self.listenToClient,args = (client,address)).start()
# send the client a connection message
# res = {
# 'cmd': 'connected',
# }
# response = dumps(res)
# client.send(response.encode('utf-8'))
def listenToClient(self, client, address):
# set a buffer size ( could be 2048 or 4096 / power of 2 )
size = 1024
while True:
try:
# try to receive data from the client
data = client.recv(size).decode('utf-8')
if data:
data = loads(data.rstrip('\0'))
if self.debug:
print(datetime.now())
print('CLIENT Data Received', client)
print('Data:')
pprint(data, width=1)
print('\n')
#send a response back to the client
res = {
'cmd': data['cmd'],
'data': data['data']
}
response = dumps(res)
client.send(response.encode('utf-8'))
else:
raise error('Client disconnected')
except:
if self.debug:
print(datetime.now())
print('CLIENT Disconnected:', client, '\n')
client.close()
return False
if __name__ == "__main__":
ThreadedServer('127.0.0.1', 8008, timeout=86400, debug=True).start()
Here is some example code I have showing a threaded socket connection.
def sock_connection( sock, host ):
"Handle socket"
pass
while 1:
try:
newsock = sock.accept()
thread = Thread( target=sock_connection, args=newsock )
thread.start()
except Exception, e:
print "error on socket connection: " % e)

Python TCP socket doesn't close?

Maybe someone here will have a response for this thing which is just driving me insane.
To make it simple, I'm making a kind of proxy. Whenever it receives something, it forwards everything to a server, and sends back the response. So there is one socket always listening on port 4557 for clients, and for each incoming connection, there is a new socket created on a random port to connect to the server port 4556.
Clients <==> Proxy <==> Server
Also, there another socket which is instantiated and listening for requests coming from the server and to be forwarded to the corresponding client.
Here is an example:
Client A connects to proxy on port 4557
Proxy creates a socket to Server on port 4556
Along with that, it creates a socket listening on port 40100
Client sends stuff, forwarded to Server
Client disconnects. Close client connection and socket to server
Some time later, Server sends stuff to proxy on port 40100
Everything's forwarded to Client A (port 40100 corresponding to Client A)
And so on..
So far in my tests, I use a simple python script for sending a unique tcp packet to the proxy, along with a dump server showing received data and echoing back.
So the issue is that when a connection to the proxy is closed, the connection to the Server should also be closed with "sock.close()". However it just seems to be completely ignored. The socket remains as ESTABLISHED.
About the code now.
A few notes.
DTN and Node are respectively Server and Clients.
runCallback is called in a loop until thread dies.
finalCallback is called when the thread is dying.
Associations between remote hosts (Client), proxy ports (to Server) and proxies are kept in the dictionaries: TCPProxyHostRegister (RemoteHost => Proxy), TCPProxyPortRegister (Port => Proxy), TCPPortToHost (Port => RemoteHost).
The first class is TCPListenerThread.
It just listen on a specific port and instantiate proxies (one for each Client=>Server couple and Server=>Client couple) and forward them connections.
class TCPListenerThread(StoppableThread):
def __init__(self, tcp_port):
StoppableThread.__init__(self)
self.tcp_port = tcp_port
self.sock = socket.socket( socket.AF_INET, # Internet
socket.SOCK_STREAM ) # tcp
self.sock.bind( (LOCAL_ADDRESS, self.tcp_port) )
self.sock.listen(1)
def runCallback(self):
print "Listen on "+str(self.tcp_port)+".."
conn, addr = self.sock.accept()
if isFromDTN(addr):
tcpProxy = getProxyFromPort(tcp_port)
if not tcpProxy:
tcpProxy = TCPProxy(host, True)
else:
host = addr[0]
tcpProxy = getProxyFromHost(host)
if not tcpProxy:
tcpProxy = TCPProxy(host, False)
tcpProxy.handle(conn)
def finalCallback(self):
self.sock.close()
Now comes the TCP Proxy:
It associates a remote host (Client) with a port connecting to Server.
If it's a connection coming from a new Client, it will create a new listener (see above) for the Server and create a socket ready to forward everything to Server.
class TCPProxy():
def __init__(self, remote, isFromDTN):
#remote = port for Server or Remote host for Client
self.isFromDTN = isFromDTN
self.conn = None
#add itself to proxy registries
#If listening from a node
if not isFromDTN:
#Set node remote host
self.remoteHost = remote
TCPProxyHostRegister[self.remoteHost] = self
#Set port to DTN interface + listener
self.portToDTN = getNewTCPPort()
TCPPortToHost[self.portToDTN] = self.remoteHost
newTCPListenerThread(self.portToDTN)
#Or from DTN
else:
self.portToDTN = remote
TCPProxyPortRegister[self.portToDTN] = self
self.remoteHost = getRemoteHostFromPortTCP(self.portToDTN)
def handle(self, conn):
print "New connection!"
#shouldn't happen, but eh
if self.conn != None:
self.closeConnections()
self.conn = conn
#init socket with remote
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
if self.isFromDTN:
self.sock.connect((self.remoteHost, 4556)) #TODO: handle dynamic port..
else:
self.sock.connect((DTN_Address, DTN_TCPPort))
#handle connection in a thread
self.handlerThread = newTCPHandlerThread(self)
#handle reply in a therad
self.replyThread = newTCPReplyThread(self)
def closeConnections(self):
try:
if self.conn != None:
print "Close connections!"
self.sock.close()
self.conn.close()
self.conn = None
self.handlerThread.kill()
self.replyThread.kill()
except Exception, err:
print str(err)
#pass
def forward(self, data):
print "TCP forwarding data: "+data
self.sock.send(data)
def forwardBack(self, data):
print "TCP forwarding data back: "+data
self.conn.send(data)
In this proxy class, I instantiate two classes, TCPHandlerThread and TCPReplyThread. They are responsible for forwarding to Server, and forwarding back to Client, respectively.
class TCPHandlerThread(StoppableThread):
def __init__(self, proxy):
StoppableThread.__init__(self)
self.proxy = proxy
def runCallback(self):
test = False
while 1:
data = self.proxy.conn.recv(BUFFER_SIZE)
if test:
self.proxy.sock.close()
test = True
if not data:
break
print "TCP received data:", data
self.proxy.forward(data)
self.kill()
def finalCallback(self):
self.proxy.closeConnections()
class TCPReplyThread(StoppableThread):
def __init__(self, proxy):
StoppableThread.__init__(self)
self.proxy = proxy
def runCallback(self):
while 1:
data = self.proxy.sock.recv(BUFFER_SIZE)
if not data:
break
print "TCP received back data: "+data
self.proxy.forwardBack(data)
self.kill()
def finalCallback(self):
self.proxy.closeConnections()
You see that whenever a connection is closed, the thread dies and the other connection (Client/Server to proxy or Proxy to Server/Client) should be closed in Proxy.closeConnections()
I noticed that when closeConnections() is "data = self.proxy.conn.recv(BUFFER_SIZE)", it goes well, but when it's called even right after the latter statement, it goes wrong.
I wiresharked TCP, and the proxy doesn't send any "bye signal". The socket state doesn't go to TIME_WAIT or whatever, it just remains ESTABLISHED.
Also, I tested it on Windows and Ubuntu.
On Windows it goes exactly as I explained
On Ubuntu, it works well for usually (not always), 2 connections, and the third time I connect with the same client in exactly the same way to the proxy, it goes wrong again exactly as explained.
Here are the three files i'm using so that you can have a look at the whole code. I'm sorry the proxy file might not be really easy to read. Was SUPPOSED to be a quick dev.
http://hognerud.net/stackoverflow/
Thanks in advance..
It's surely something stupid. Please don't hit me too hard when you see it :(
First I'm sorry that I currently have not the time to actually run and test your code.
But the idea came to my mind, that your problem might actually have something todo with using blocking mode vs. non-blocking mode on the socket. In that case you should checkout the "socket" module help in the python documentation, especially socket.setblocking().
My guess is, that the proxy.conn.recv() function only returns, when actually BUFFER_SIZE bytes where received by the socket. Because of this the thread is blocked until enough data was received and therefore the socket doesn't get closed.
As I said first, this is currently just a guess, so please don't vote me down if it doesn't solve the problem...

Categories