Create new TCP Connection for every http requests in Python - centos

For my college project I am trying to develop a python based traffic generator.I have created 2 CentOS machines on vmware and I am using 1 as my client and 1 as my server machine. I have used IP aliasing technique to increase number of clients and severs using just single client/server machine. Upto now I have created 50 IP alias on my client machine and 10 IP alias on my server machine. I am also using multiprocessing module to generate traffic concurrently from all 50 clients to all 10 servers. I have also developed few profiles(1kb,10kb,50kb,100kb,500kb,1mb) on my server(in /var/www/html directory since I am using Apache Server) and I am using urllib2 to send request to these profiles from my client machine. Here while running my scripts when I monitor number of TCP Connections it is always <50. I want to increase it to say 10000. How do I achieve this? I thought that if a new TCP Connection is established for every new http request, then this goal can be achieved. Am I on right path? If not kindly guide to me correct path.
'''
Traffic Generator Script:
Here I have used IP Aliasing to create multiple clients on single vm machine.
Same I have done on server side to create multiple servers. I have around 50 clients and 10 servers
'''
import multiprocessing
import urllib2
import random
import myurllist #list of all destination urls for all 10 servers
import time
import socbindtry #script that binds various virtual/aliased client ips to the script
response_time=[] #some shared variables
error_count=multiprocessing.Value('i',0)
def send_request3(): #function to send requests from alias client ip 1
opener=urllib2.build_opener(socbindtry.BindableHTTPHandler3) #bind to alias client ip1
try:
tstart=time.time()
for i in range(myurllist.url):
x=random.choice(myurllist.url[i])
opener.open(x).read()
print "file downloaded:",x
response_time.append(time.time()-tstart)
except urllib2.URLError, e:
error_count.value=error_count.value+1
def send_request4(): #function to send requests from alias client ip 2
opener=urllib2.build_opener(socbindtry.BindableHTTPHandler4) #bind to alias client ip2
try:
tstart=time.time()
for i in range(myurllist.url):
x=random.choice(myurllist.url[i])
opener.open(x).read()
print "file downloaded:",x
response_time.append(time.time()-tstart)
except urllib2.URLError, e:
error_count.value=error_count.value+1
#50 such functions are defined here for 50 clients
process=[]
def func():
global process
process.append(multiprocessing.Process(target=send_request3))
process.append(multiprocessing.Process(target=send_request4))
process.append(multiprocessing.Process(target=send_request5))
process.append(multiprocessing.Process(target=send_request6))
#append 50 functions here
for i in range(len(process)):
process[i].start()
for i in range(len(process)):
process[i].join()
print"All work Done..!!"
return
start=float(time.time())
func()
end=float(time.time())-start
print end

Related

How to host twisted python code to the Internet?

Currently I Have This Following Code Which Simply Echo's The Data Which Is Sent To The Server and Shows The Number Of Active Connections In The Server To The Clients and Sends Some Info.
from twisted.internet.protocol import Protocol , Factory
from twisted.internet import reactor
from twisted.internet.endpoints import TCP4ServerEndpoint
connections = -1
class echo_simple(Protocol):
def connectionMade(self):
global connections
connections += 1
self.transport.write(f'Number of active connections in the server are: {connections} '.encode('utf-8'))
def connectionLost(self,*args , **kwargs):
global connections
connections -= 1
print(':: N :: A Connection Just Closed :: N ::')
def dataReceived(self, data):
data = data.decode('utf-8')
print(f':C: {data} ')
self.transport.write("\n Server Successfully Received Your Message!".encode('utf-8'))
self.transport.write(f"\n |THE MESSAGE YOU SENT IS : {data}|".encode('utf-8'))
self.transport.write(f'\n Closing The Connection As This is Just An Echo Server'.encode('utf-8'))
self.transport.loseConnection()
class Server_factory(Factory):
def buildProtocol(self, addr):
print(" |^INFO^| Created An Instance ")
return echo_simple()
endpoint = TCP4ServerEndpoint(reactor, 8009)
endpoint.listen(Server_factory())
reactor.run()
My Problem Is The Server Is Currently Listening In The LocalHost , I want to host this in the internet globally !
Say for example i have an domain called www.examplecode.com
Instead of listening in the localhost , how to change my code so that it listens to the www.examplecode.com instead of localhost ?
You need the domain to point to a server, that runs this code.
When you buy the domain, the registrar you buy it from usually gives you an interface to setup the dns configuration, usually you'll setup an AA or CNAME record to point to the ip or existing other domain that points to the server you will use to run the code.
You will usually rent a server from another company (there are plenty of them), that will run in a data center and will be taken care of, connect to that server, and deploy your code on it (often through ssh), and make it listen on 0.0.0.0 so it accepts connections from anywhere. You then get the IP of this server, and use it to setup the DNS in the interface provided by your registrar.
Alternatively, you can use a computer at your home, if you configure your router to direct connections on the 440 and 80 port to the local ip of this PC, and you put the ip of your home connection in the registrar DNS configuration (hopefully you have a static ip though).
Anyway, it's a bit of a wide subject for a stackoverflow question (and it might not even be on topic for stackoverflow, maybe it's more a serverfault question, or a superuser, one.

Using UDP between remote server and client

I am currently working on a project that needs a UDP communication between a server Amazon Frankfurt) and several hosts (Arduino). I need to be able to send JSON data from server to a host over UDP and it needs to work in real time (time is a real constraint here). Also, periodically a host will speak to server to inform server about its status.
The problem I'm facing is that although I can ping the server, when I create the UDP socket with a port, I get this error (for any port):
errno99: cannot assign requested address
I also believe that since the hosts are in different countries, I can only get router's IP. Hosts will be given to users therefore it is impossible to alter user's router by hand. I need to use something that can handle these by code.
I have been searching on Hole Punching and other techniques. I cannot decide what suits more to my scenario here. Sorry for my lack of network information, any help or guidance as "read or search these techniques" are appreciated.
This code runs on server:
import socket
import time
#Host's public IP
UDP_IP_ADDRESS = "178.243.98.86"
UDP_PORT_NO = 13000
Destination = (UDP_IP_ADDRESS,UDP_PORT_NO)
Message = "Hello, Server"
senderSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while True:
senderSock.sendto(Message, Destination)
time.sleep(1);
And this code runs on my machine:
import socket
#Server's public IP
UDP_IP_ADDRESS = "172.31.46.111"
UDP_PORT_NO = 13000
recieverSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
recieverSock.bind((UDP_IP_ADDRESS, UDP_PORT_NO))
while True:
data, addr = recieverSock.recvfrom(1024)
print "Message: ", data
Server
# Host's public IP
UDP_IP_ADDRESS = "178.243.98.86"
You cannot rely on 178.243.98.86. Your arduinos are behind one or several NATs. With NAT, when a packet leaves a network, your packets source and/or destination addresses (and most likely ports) get rewritten. When this conversion happens, a device responsible for NAT remembers this conversion, but only for a limited period of time. The period usually defaults to 24h.
In order to overcome this issue, it's up to clients to initiate conversations with the server. Introduce a new message type to your protocol saying something like hey it's me, client #34. The server should be associating source IP and port of the received message with client #34 for some period of time, like hours.
In this case the server binds a socket to an address and port as well as a client. And beware that hey it's me, client #34 sent over UDP is not encrypted and is extremely vulnerable to record and replay attacks. I believe an emergency system should be encrypted.
Client
# Server's public IP
UDP_IP_ADDRESS = "172.31.46.111"
172.31.46.111 cannot be server's public IP, because it is an address from an IPv4 private space. You probably meant to say "host's private address". It makes sense to bind to such an address. You get an error most likely because you have incorrectly determined the IP address of your host.
There are several ways to get the correct IP. If you use DHCP (you use it if you've never though about what IPs to use in your SOHO), log into your nearest router's admin interface and check the DCHP Pool. Alternatively, Linux and Windows have terminal commands to do the same. For Arduino, you have probably assigned it a static address. If so, bind to it.
You also seem to open a tcp socket on the server, and connect to it from client via udp socket. Is this intentional?
gsn

capturing TCP packets flow

Problem statement:
Suppose a parent server is hosted on a machine IP: 1.1.1.1 and that server some time communicates with three different servers say A (1.1.1.2), B (1.1.1.3), C (1.1.1.4). Those servers may be database servers or any other servers.
Now from your browser you can send a http request to 1.1.1.1/somePage.htm, as a result some TCP packet will go to the server 1.1.1.1, and 1.1.1.1 can send and receive some TCP packets from A,B,C as well.
Aim is to get the information of all TCP packets from the browser machine, without installing any agent software in any servers.
One solution is we can write a code at the 1.1.1.1 server machine that will filter all the TCP packets with respect to respective IPs. But I don’t want that solution.
Is there any way to solve this issue? Is it possible to introduce new protocol for this? But server codes can’t be modified.
Does "any agent software" includes something like Wireshark? Usually the way to look at all datagrams received is by using a sniffer like Wireshark or you can use tcpdump in Linux servers.
You can also use Netfilter to handle received packets in the server an take certain actions on them.
If all the above is included in what you don't want to do the only alternative I see is to add another server in the middle between the browser and the web server (or between the server and a load balancer if you have a load balancer) that acts only as a router or bridge. In that machine you can inspect and filter TCP segments with all the available tools.

Two (or more) socket client connections on one machine

I have a simple node.js client and server programs running on one machine and when I try to connect to the server with second instance of client program simultaneously I get EADDRINUSE, Address already in use error. Is it possible to have two or more TCP based socket client connections (created with createConnection) to one server (created with createServer) on the same machine, or only one client program can be connected to the server at the same time?
Yes, it's possible. Infact, very common. Many applications open dozens, or hundreds of connections to the same server. It sounds like your client program is binding on a port. Only the server should be binding on a port. You should verify.
The client will usually use a random port between 1024-65535, as assigned by your OS. You don't need to worry about it. Since the client is initiating a connection to the server, the server port must unique to one program. Which is why your problem signifies you are trying to start the server twice. Please see http://www.tcpipguide.com/free/t_TCPIPClientEphemeralPortsandClientServerApplicatio.htm

Creating client and server sockets in the same file

I would have to design a job scheduling system which works like - users (clients) would deposit jobs (executables) to a server. I have three files - client.c, jobQ.c and server.c. The jobQ would take client requests, and send them to the server on specific timestamps (if a user wants to run job X on server Y at 07-29-2010 3:34 AM, then the jobQ would store it in a stack, and when time comes and if the server is free, it sends the job to the server).
jobQ.c would act as a server for client.c and as a client for server.c.
I have used TCP/IP sockets to program these, and the problem I am facing is while creating multiple sockets in jobQ.c. Is it possible for the same file to have client and server sockets? The error points to this line in jobQ.c:
sockSer = socket(AF_INET, SOCK_STREAM, 0);
error: lvalue required as decrement operand
...when I am opening a second socket to talk to the server.
My idea is that jobQ would open different ports to listen to clients and connect to the server.
Thanks,
Sayan