Отправка, получение с помощью сокета python

В настоящее время я пытаюсь написать процесс, который встраивает последовательность из IP-адресов в пакеты и отправляет их на n-сервер. Каждый сервер удаляет внешний IP-адрес и затем перенаправляет его на указанный IP-адрес. Я точно знаю туннелирование. Во время процесса я также хочу, чтобы сервер делал traceroute туда, где он пересылал пакет, и отправлял его обратно на предыдущий сервер.

Мой код в настоящее время будет пересылать пакеты, но он застревает при выполнении traceroute и получении его. Я считаю, что он в настоящее время застревает в цикле while на промежуточном сервере. Я думаю, что это имеет какое-то отношение ко мне, не закрывая сокеты должным образом. Любое предложение?

клиент

#!/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()

Промежуточный сервер

#!/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()

Целевой сервер

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()
1 ответ

Промежуточный сервер застрял в clisock.recv() в этом цикле, потому что условие прерывания not raw является not raw не выполняется до того, как соединение закрыто клиентом, а клиент не закрывает соединение до получения трассировки от промежуточного сервера, поэтому они ждут друг друга. Чтобы исправить это, вы можете подумать о отправке размера файла на промежуточный сервер, чтобы его можно было использовать, чтобы определить, когда цикл приема будет выполнен. Или, если ваша платформа поддерживает закрытие одной половины соединения, вы можете использовать

s.shutdown(socket.SHUT_WR)

в клиенте после отправки файла.

licensed under cc by-sa 3.0 with attribution.