我一直在尝试对我的 TCP 数据包进行分段,但我没有找到任何有用的实现。我熟悉碎片化的理论和概念,甚至遇到过一些标志,例如IP_PMTUDISC_DONT
,,IP_PMTUDISC_WANT
并IP_PMTUDISC_DO
设置它们,但wireshark的捕获总是显示DF标志为on。
我已将“lo”网络接口的 MTU 设置为 1500,因为我在服务器和客户端上都使用了 LoopBack 地址。而且我认为碎片将由网络层处理,但我猜不是这样......请帮助我处理数据包的碎片。
这是我的代码...
服务器.cpp
#include <sys/types.h>
#include <sys/socket.h>
#include <iostream>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netdb.h>
int main(){
struct sockaddr_in serv_addr, cli_addr;
char buff[255];
int FileDesc = socket(AF_INET,SOCK_STREAM, 0);
if(FileDesc < 0){
perror("Socket Creation Failed. ");
exit(EXIT_FAILURE);
}
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(5455);
if (bind(FileDesc, (const sockaddr*)&serv_addr, sizeof(serv_addr)) < 0){
perror("Bind Failed.");
exit(EXIT_FAILURE);
}
if (listen(FileDesc, 6) < 0){
perror("Listen Failed.");
exit(EXIT_FAILURE);
}
socklen_t cliLen;
int AcceptFD = accept(FileDesc, (sockaddr*)&cli_addr, &cliLen);
if(AcceptFD < 0){
perror("Accept Failed.");
exit(EXIT_FAILURE);
}
//Setting the MTU
struct ifreq ifr;
ifr.ifr_addr.sa_family = AF_INET;//address family
strncpy(ifr.ifr_name, "lo", sizeof(ifr.ifr_name));//interface name where you want to set the MTU
ifr.ifr_mtu = 1500; //your MTU size here
if (ioctl(FileDesc, SIOCGIFMTU, (caddr_t)&ifr) < 0){
perror("ioctl error.");
exit(1);
}
std::cout << ifr.ifr_ifru.ifru_mtu;
while(1){
//File Transfer
}
close(AcceptFD);
close(FileDesc);
return 0;
}
客户端.cpp
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>
#include <unistd.h>
#include <netdb.h>
#include <string.h>
#include <arpa/inet.h>
int main(){
struct sockaddr_in serv_addr;
char buffer[255];
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0){
perror("Socket Creation Failed.");
exit(EXIT_FAILURE);
}
FILE *fp;
char *filename = "File.txt";
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
inet_aton("127.0.0.1", &serv_addr.sin_addr);
serv_addr.sin_port = htons(5455);
int conn = connect(fd, (const sockaddr*)&serv_addr, sizeof(serv_addr));
if (conn < 0){
perror("Connect Failed. ");
exit(EXIT_FAILURE);
}
while(1){
//File Recieve
}
close(fd);
return 0;
}
这也引出了一个问题,我将如何以相同的顺序重新组装我的数据包?谢谢你。