Итак, я работаю над проектом, который требует, чтобы я симулировал протокол TCP с тремя рукопожатиями, используя UDP. Я хочу разделить проект на две части: первая - установить sh и закрыть соединение; во-вторых, реализовать протокол управления потоком без потери пакетов. Поскольку клиент и сервер будут взаимодействовать друг с другом, мне нужны два сокета, а значит, мне также нужны два порта - 19990 и 19991 - для отправки и получения данных между клиентом и сервером.
У меня возникли проблемы при трехстороннем рукопожатии
- Клиент -> (Отправить SYN)
- Завершить -> (Принять SYN и отправить SYN ACK)
- Клиент -> получает SYN ACK и отправляет ACK с данными
- Сервер затем устанавливает соединение и сообщает, что данные были получены
- Клиент -> Сервер ACK устанавливает соединение и получает данные. Поэтому отправьте FIN, чтобы закрыть соединение
- Сервер -> Получает FIN и закрывает соединение (с server_socket.close)
вывод на стороне клиента:
- Отправка: a, 1
- Получение: b, num: 2
- Отправка: c, 3
- Получение: d, num : 4
- Клиент выполнен
вывод на стороне сервера:
- Получение: a, num: 1
- Отправить: b, 2
- Получить c, номер: 3
- Отправить: d, 4
- Сервер завершен.
Однако я надеюсь, что они будут выглядеть так:
client.py
- Отправить SYN
- Отправить:, 1
- Получено: num, 2
- Получено SYN-ACK. Отправьте ACK & Data
- Отправьте: Я люблю AB C Университет в Нью-Йорке., 3
- Получите:, num: 4
- Получил ACK для данных. Отправить FIN. Соединение закрыто.
- Отправить:, 4
server.py
- Получить:, num: 1
- Получено SYN. Отправить SYN-ACK
- Отправить:, 2
- Получить: Я люблю AB C Университет в Нью-Йорке., Num: 3
- Получить ACK. Соединение установлено. Полученные данные. Отправить ACK
- Отправить:, 4
- Получить:, num: 4
- Соединение закрыто
Вот код, который у меня есть для server.py:
import socket
import sys
import struct
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(("0.0.0.0", 19990))
def send(c,num):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ss = struct.pack("!50si",c.encode(),num)
s.sendto(ss,("127.0.0.1",19991))
s.close()
print("Send:%s,%d" % (c,num))
def recv():
global server_socket
data, addr = server_socket.recvfrom(1024)
str,num = struct.unpack("!50si",data)
str = str.decode("utf-8").replace("\0","")
print("Receive:%s,num:%d" % (str,num))
return str,num
while True:
str,num = recv()
num = num + 1
str = chr(ord(str)+1)
send(str,num)
if str == "d":
break
print("Server Done.")
server_socket.close()
Вот код, который у меня есть для client.py
import socket
import sys
import struct
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind(("0.0.0.0", 19991))
def send(c,num):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ss = struct.pack("!50si",c.encode(),num)
s.sendto(ss,("127.0.0.1",19990))
s.close()
print("Send:%s,%d" % (c,num))
def recv():
global server_socket
data, addr = server_socket.recvfrom(1024)
str,num = struct.unpack("!50si",data)
str = str.decode("utf-8").replace("\0","")
print("Receive:%s,num:%d" % (str,num))
return str,num
str = 'a'
num = 1
while True:
send(str,num)
str,num = recv()
if str == "d":
break
str = chr(ord(str)+1)
num = num + 1
print("Client done.")
server_socket.close()
#If the number = 1, sender will send and the receiver will receive
#c is the data and num is the sequence number, for the first three msgs it is the flag
#The payload we want to send is seven characters with one sentence
#Window size is 4 with 4 being four characters
#First package is "i lo"
#I is sent as a package, then space as a package, then l as a package, and o as a package as a window
#First byte is i, second is space, l is third, o is forth.
#Send out 4 bytes, receive 4 acknowledgements.
#When the sender sends out the last byte "."
#To do: Change 'a' to past establishment
#Instead of Send: a, 1
#professor wants to see "Send Think message"
#Receive: Think ack message
#Send: Ack msg
#a b c d are just give you some examples