Мне необходимо использовать сырые сокеты для приема GET-запроса и ответа на него.
Сначала реализовал это через SOCK_STREAM, но не знаю как сделать через SOCK_RAW.
Вот как выглядит сервер, пока он только ловит пакеты, но не отвечает:
import socket
import struct
act_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_TCP)
for x in range(10):
print x
response, addr = act_socket.recvfrom(65535)
if not response:
break
elif addr[0] == '127.0.0.1':
#take first 20 characters for the ip header
ip_header = response[0:20]
#now unpack them
iph = struct.unpack('!BBHHHBBH4s4s' , ip_header)
version_ihl = iph[0]
version = version_ihl >> 4
ihl = version_ihl & 0xF
iph_length = ihl * 4
ttl = iph[5]
protocol = iph[6]
s_addr = socket.inet_ntoa(iph[8]);
d_addr = socket.inet_ntoa(iph[9]);
print 'Version : ' + str(version) + ' IP Header Length : ' + str(ihl) + \
' TTL : ' + str(ttl) + ' Protocol : ' + str(protocol) + \
' Source Address : ' + str(s_addr) + ' Destination Address : ' + str(d_addr)
tcp_header = response[iph_length:iph_length+20]
#now unpack them
tcph = struct.unpack('!HHLLBBHHH' , tcp_header)
source_port = tcph[0]
dest_port = tcph[1]
sequence = tcph[2]
acknowledgement = tcph[3]
doff_reserved = tcph[4]
tcph_length = doff_reserved >> 4
print 'Source Port : ' + str(source_port) + ' Dest Port : ' + \
str(dest_port) + ' Sequence Number : ' + str(sequence) + ' Acknowledgement : ' + \
str(acknowledgement) + ' TCP header length : ' + str(tcph_length)
h_size = iph_length + tcph_length * 4
#get data from the packet
data = response[h_size:]
print "lenth of data: ", len(response), "required: ", h_size
print 'Data : ' + data
Вот что делает клиент (получение ответа пока убрал):
import socket
import httplib
host = "127.0.0.1"
port = 8080
httpServ = httplib.HTTPConnection(host, port)
httpServ.connect()
httpServ.request('GET', "mysite.com?addr=index.html")
# response = httpServ.getresponse()
# if response.status == httplib.OK:
# print "Output from HTML request"
# print response.read()
httpServ.close()
Сейчас клиент отправляет пакеты, но получает ошибку
socket.error: [Errno 111] Connection refused
при попытке соединиться (httpServ.connect())
Вопросов два:
1. Как должно быть реализован обмен пакетами между клиентом и сервером, использую сырые пакеты на сервере; нужно ли реализовывать тройное рукопожатие?
2. Сервер принимает только ip и tcp заголовок, данных нет. В чем ошибка?