简体   繁体   中英

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM