Why does my UDP pinger client only timeout? - python

I've made a UDP Pinger server side, however this UDP Pinger client only sends request time outs. I'm trying to make a pinger that sends 10 pings to the server.
import time
from socket import *
serverName = ''
serverPort = 12000
ClientSocket = socket(AF_INET, SOCK_DGRAM)
ClientSocket.settimeout(1)
ping = 1
message = 'ping'
counter = 10
i = 0
remain = counter - i
while counter < i :
i = i + 1
addr = ("", 120000)
start = time.time()
ClientSocket.sendto(message, (serverName,
serverPort))
while ping < 11:
try:
message, server = ClientSocket.recvfrom(1024)
end = time.time()
elapsed = end - start
print (message + " " + str(ping) + " " +
str(elapsed))
except timeout:
print ('REQUEST TIMED OUT')
ping = ping + 1

Related

UDP Ping Client - Python

I am trying to implement a UDP Pinger. In the client code that I wrote, the try statement is not evaluating and just the packet loss message is printing. It is clear that the try statement is not even being hit. I have tried so many different things and nothing has fixed it. Please let me know if you know the issue.
Here is the client code:
import random
import time
import sys
from socket import *
if len(sys.argv) != 3:
print("Usage: python UDPPingerClient <server ip address> <server port no>")
exit(0)
client_socket = socket(AF_INET, SOCK_DGRAM)
server = (sys.argv[1], int(sys.argv[2]))
client_socket.settimeout(1)
for i in range(0, 5):
start_time = time.time()
host_name = gethostname()
server_ip = gethostbyname(host_name)
msg = 'PING ' + str(server_ip) + " " + str(i)
try:
client_socket.sendto(msg.encode(), server)
client_socket.settimeout(1)
client_socket.recv(1024)
end_time = time.time()
rtt = (end_time - start_time) * 1000
msg += " " + str(format(rtt, '.3f')) + "ms\n"
print(msg)
except timeout:
timeout_msg = 'PING ' + str(server_ip) + " " + str(i + 1) + " " + 'Lost\n'
print(timeout_msg)
This is the server code:
import random
import time
import sys
from socket import *
if (len(sys.argv) != 2):
print("Required arguments: port")
exit(0)
port = int(sys.argv[1])
serverSocket = socket(AF_INET, SOCK_DGRAM)
serverSocket.bind(('', port))
LOSS_RATE = 0.3
AVERAGE_DELAY = 100
while True:
rand = random.uniform(0, 1)
message, address = serverSocket.recvfrom(1024)
print(message)
if rand < LOSS_RATE:
print("Reply not sent.")
continue
delay = random.randint(0.0, 2*AVERAGE_DELAY)
print(delay)
time.sleep(delay/1000)
serverSocket.sendto(message, address)
print("Reply sent.")

udp client/server with resending messages

I have a client and a server. The server sends a random number to the client and if it is less than 4, the client responds unsuccessfully.
SERVER:
import random
from socket import *
serverSocket = socket(AF_INET, SOCK_DGRAM)
serverSocket.bind(('', 12000))
while True:
rand = random.randint(2, 4)
message, address = serverSocket.recvfrom(1024)
message = (message.decode()+" СЛУЧАЙНОЕ ЧИСЛО: "+str(rand)).upper()
print("Сервер готов!")
print("Случайное число: "+str(rand))
if rand < 4:
continue
serverSocket.sendto(message.encode(), address)
Client:
from time import *
from socket import *
localhost = '127.0.0.1'
for i in range(1, 11):
clientSocket = socket(AF_INET, SOCK_DGRAM)
date_current = ctime()
startTime = time()
clientSocket.settimeout(0.5)
try:
requestMessage = bytes("Ping " + str(i) + " " + date_current, 'utf8')
clientSocket.sendto(requestMessage, (localhost, 12000))
mess, rand = clientSocket.recvfrom(1024)
endTime = time()
rtt = endTime - startTime
print(mess.decode())
print("Ответ "+localhost+" подтверждено: "+str(float(rtt)))
print()
except:
print(requestMessage.decode())
print("Время вышло")
print()
I want the client to send a message to the server in case of failure and the server to regenerate the number and send it to the client until there is a response about luck (more than 4)

How do i get the socket to continue listening to the client and continuosly print information from the client

Server Side (server prints the first line of information sent from the client then it JUST STAYS open and doesn't seem to continue listening it just stays open. Is there a way to get the server to listen to the client more and print?)
import time
import socket
import signal
from datetime import datetime
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('localhost', 8089))
serversocket.listen(1024) # become a server socket, maximum 5 connectionn
def clientsocketentry():
while True:
connection, addr = serversocket.accept()
buf = connection.recv(64)
if not buf:
break
elif buf == 'killsrv':
connection.close()
sys.exit()
else:
print (buf)
buf = buf.decode("utf-8")
buf = buf.split(',')
serverLong = buf[0]
print('Longitude:' + '' + serverLong)
serverLat = buf[1]
print('Lattitude:' + '' + serverLat)
serverAlt = buf[2]
print('Altitude:' + '' + serverAlt)
serverTime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print('Time of Entry:' + ' ' + serverTime)
connection.close()
clientsocketentry()
Client Side (I am only able to send one of the strings of information then the server stays open ut does not take more information from the client)
import socket
import time
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect(('localhost', 8089))
a = '39.163100,-76.899428,0'
clientsocket.send(a.encode('utf-8'))
time.sleep(5)
a = '4.2,2.2415,0'
clientsocket.send(a.encode('utf-8'))
time.sleep(5)
a = '43454,354354,35435'
clientsocket.send(a.encode('utf-8'))
time.sleep(5)
a = '435742.,35.452,52434'
clientsocket.send(a.encode('utf-8'))
time.sleep(5)
clientsocket.close()
If you accept one single connection at a time (no need for a 1024 backlog then...) you can simply nest 2 loops: the outer one waiting for new connections the inner one processing input from the only one established connection. If you need to process more than one connection, you will have to use select or threads.
Here is an example for one single connection:
def clientsocketentry():
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('localhost', 8089))
serversocket.listen(5) # become a server socket, maximum 5 connectionn
cont = True
while cont:
connection, addr = serversocket.accept()
while True:
buf = connection.recv(64)
if len(buf) == 0: # end of connection
connection.close()
break
elif buf == b'killsrv': # request for closing server (beware of the byte string)
connection.close()
serversocket.close()
cont = False
break
else:
print (buf)
buf = buf.decode("utf-8")
buf = buf.split(',')
serverLong = buf[0]
print('Longitude:' + '' + serverLong)
serverLat = buf[1]
print('Lattitude:' + '' + serverLat)
serverAlt = buf[2]
print('Altitude:' + '' + serverAlt)
serverTime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print('Time of Entry:' + ' ' + serverTime)
# connection.close() # wait for client to close
You are closing the socket at the end of your print logic in the ClientSocketEntry function.
serverTime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
print('Time of Entry:' + ' ' + serverTime)
connection.close()
Instead of closing the connection there only close it when the user sends killsrv
Because every time you close the connection on the socket it is saying that you are expecting another client to connect to the server. So maybe before going into the while statement accept the connection and then pass it into the while statement, because the way you have it structured at the moment is expecting multiple connections from different clients.

Why is my traceroute failing to contact a server partway through running?

I've been struggling to get my traceroute up and running, and I was hoping for a bit of help. I'm running this with Python 2.7 on a Linux VM. Below is my source code (please ignore the spacing on the first line; I had a hard time figuring out SO's code formatting tool, but the indentations are correct in my local copy.)
def main(dest_name):
dest_addr = socket.gethostbyname(dest_name)
# Define UDP and ICMP
udp = socket.getprotobyname('udp')
icmp = socket.getprotobyname('icmp')
timer = 1
port = 54321
maxHops = 40
totalRTT = 0
while True:
# Create sender and receiver. Sender uses UDP, receiver uses IDMP
sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, udp)
# Assign TTL to sender, increment TTL
sender.setsockopt(socket.SOL_IP, socket.IP_TTL, timer)
receiver = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
receiver.settimeout(15.0)
# Bind socket and send message from sender to receiver
receiver.bind(("", port))
sender.sendto("", (dest_name, port))
# Ensures that not receiving won't stall the program
# receiver.setblocking(0)
addr = None
name = None
count = 0
try:
# Keep track of RTT
startTime = time.time()
# Reads an array of 512-byte sized blocks from sender into addr
(_,addr) = receiver.recvfrom(512)
addr = addr[0]
# Try to get site name
try:
name = socket.gethostbyaddr(addr)[0]
except socket.error:
name = addr
# Process socket errors
except socket.error as exc:
pass
# Close both sockets
finally:
sender.close()
receiver.close()
endTime = time.time()
# Record RTT, total RTT, convert to ms
RTT = (endTime - startTime) * 1000
totalRTT += RTT
if addr is not None:
host = "%s (%s)" % (name, addr)
else:
host = "*"
print("%d\t%s" % (timer, host))
print(" %f" % RTT + " ms")
timer += 1
if addr == dest_addr or timer > maxHops:
print("Total RTT: %f\n" % totalRTT)
print("Hop count: %d\n" % timer)
break
if __name__ == "__main__":
main('www.google.com')
My output looks something like this:
1 129.22.144.2 (129.22.144.2)
3.091097 ms
2 10.2.0.98 (10.2.0.98)
4.683971 ms
3 10.2.3.169 (10.2.3.169)
6.258011 ms
4 *
15015.315056 ms
5 *
15015.240908 ms
It continues to time out until my max hop count is reached. Does anyone have suggestions?
Thanks!
Did some research. The issue ended up being the port number I was using. When writing a traceroute, use port 33434.

Sending, receiving with python socket

I'm currently trying to write process that embeds a sequence of n IPs into packets and send it off to n server. Each server remove the outermost IP and then forward it to said IP. This is exactly like tunneling I know. During the process I also want the server to do a traceroute to where it's forwarding the packet and send that back to the previous server.
My code currently will forward the packets but it's stuck on performing the traceroute and getting it. I believe it's currently stuck in the while loop in the intermediate server. I think it's having something to do with me not closing the sockets properly. Any suggestion?
Client
#!/usr/bin/env python
import socket # Import socket module
import sys
import os
s = socket.socket() # Create a socket object
host = socket.gethostname() # Get local machine name
port = 17353 # Reserve a port
FILE = raw_input("Enter filename: \n ")
NIP = raw_input("Enter Number of IPs: ")
accepted_IP = 0
IP= []
while accepted_IP < int(NIP):
IP.append(raw_input("Enter destination IP: \n"))
accepted_IP +=1
#cIP = raw_input("Enter intemediate IP: \n ")
ipv = raw_input("Enter IP version... 4/6")
try:
s.connect((host, port))
print "Connection sucessful!"
except socket.error as err:
print "Connection failed. Error: %s" %err
quit()
raw = open(FILE,"rb")
size = os.stat(FILE).st_size
ls = ""
buf = 0
for i in IP:
while len(i) < 15:
i += "$"
ls += i
header = ipv+NIP+ls+FILE
print ls
s.sendall(header + "\n")
print "Sent header"
data = raw.read(56) +ipv + NIP + ls
print "Begin sending file"
while buf <= size:
s.send(data)
print data
buf += 56
data = raw.read(56) + ipv + NIP + ls
raw.close()
print "Begin receiving traceroute"
with open("trace_log.txt","w") as tracert:
trace = s.recv(1024)
while trace:
treacert.write(trace)
if not trace: break
trace = s.recv(1024)
print "finished forwarding"
s.close()
Intermediate server
#!/usr/bin/env python
import socket
import subprocess
srvsock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
srvsock.bind( (socket.gethostname(), 17353) )
srvsock.listen( 5 ) # Begin listening with backlog of 5
# Run server
while True:
clisock, (remhost, remport) = srvsock.accept() #Accept connection
print
d = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
header = ""
while True:
b = clisock.recv(1)
if b == "\n":
break
header += b
num = 15 * int(header[1]) + 2
file_name = header[num:]
nheader = header[0]+ str(int(header[1])-1) + header[17:]
d.connect((socket.gethostname(), 12355))
d.sendall(nheader+'\n')
print "begin forwarding"
while True:
raw = clisock.recv(56 + num) # recieve data
ip = raw[-15:] # extract IP
ipv, NIP = raw[57] , str(int(raw[57])-1)
if NIP == "0":
while (raw):
print "stuck in this loop"
d.send(raw[:56])
raw=clisock.recv(56+num)
if not raw: break
else:
while (raw):
print raw[:57] + NIP + raw[59:-15]
print "\n"
d.send(raw[:57] + NIP + raw[59:-15])
raw = clisock.recv(56+num)
if not raw :break
print "Finish forwarding"
d.close()
break
print "Begin traceroute"
tracrt = subprocess.Popen(['traceroute','google.com'], stdout=subprocess.PIPE)
s.sendall(tracrt.communicate()[0])
print "Finished"
clisock.close()
s.close()
Destination server
import socket
s = socket.socket()
host = socket.gethostname()
port = 12355
s.bind((host,port))
s.listen(5)
while True:
csock, (client, cport) = s.accept()
print client
header = ""
while True:
b = csock.recv(1)
if b == "\n":
break
header += b
file_name = header[2:]
r = open("File_test_"+file_name,"wb")
print 'Opening file for writing'
while True:
print "Begin writing file" + " " + file_name
raw = csock.recv(56)
while (raw):
print raw
r.write(raw)
raw = csock.recv(56)
r.flush()
r.close()
print "finish writing"
break
print "closing connection"
csock.close()
s.close()
The intermediate server is stuck in clisock.recv() in this loop because the break condition not raw isn't met before the connection is closed by the client, and the client doesn't close the connection before receiving the traceroute from the intermediate server, so they are waiting on each other.
To remedy this, you might consider sending the file size to the intermediate server, so that it can be used to determine when the receive loop is done. Or, if your platform supports shutting down one half of the connection, you can use
s.shutdown(socket.SHUT_WR)
in the client after sending the file.

Categories