- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我目前正在尝试仅使用原始套接字来创建 Linux echo 客户端。我在一台计算机上运行一个普通的 TCP 服务器,而在客户端我使用的是原始 TCP 套接字。我在客户端运行 Libpcap 来接收数据包并在收到数据包时进行回复。我完成了三次握手,并在客户端和服务器之间建立了连接。
我能够发送带有数据的第一个 ACK、PSH、ACK(数据包 3 和 4),并使用我最初发送的数据(数据包 5 和 6)从服务器接收回复。
关于如何阻止 PSH、ACK 发送的任何想法?我试过发送 ACK 但它不会停止发送。下面是一个 wireshark 捕获和我正在使用的一些代码。
这是wireshark Server(192.168.1.81) Client(192.168.1.85)上的数据包截图: Wireshark capture
客户端原始 TCP 包装器
void send_raw_tcp_packet(int src_port, int dst_port, struct ifreq interface,
char* src_ip, char* dst_ip, int seq, int ack, char *data, int flags) {
struct sockaddr_in sin;
int *ip_flags, *tcp_flags, status, sending_socket;
const int on = 1;
struct tcp_packet packet;
ip_flags = (int *)calloc(4, sizeof(int));
tcp_flags = (int *)calloc(8, sizeof(int));
int payloadlen = 0;
memset(&packet, 0, sizeof(struct tcp_packet));
// IPv4 header
packet.iphdr.ip_hl = IP4_HDRLEN / sizeof(uint32_t); //header length = 5
packet.iphdr.ip_v = 4; //version = 4
packet.iphdr.ip_tos = 0; //TOS
packet.iphdr.ip_len = htons(IP4_HDRLEN + TCP_HDRLEN); //length: IP header + TCP header
packet.iphdr.ip_id = htons(0); //ID
ip_flags[0] = 0; //Zero
ip_flags[1] = 0; //Don't frag
ip_flags[2] = 0; //More frag
ip_flags[3] = 0; //Frag offset
packet.iphdr.ip_off = htons((ip_flags[0] << 15) + (ip_flags[1] << 14) + (ip_flags[2] << 13) + ip_flags[3]);
packet.iphdr.ip_ttl = 255; //TTL
packet.iphdr.ip_p = IPPROTO_TCP; //Protocol
printf("src_ip: %s\n", src_ip);
printf("dst_ip: %s\n", dst_ip);
// Source IPv4 address (32 bits)
if ((status = inet_pton(AF_INET, src_ip, &(packet.iphdr.ip_src))) != 1) {
perror("inet_pton, src_ip");
exit(EXIT_FAILURE);
}
// Destination IPv4 address (32 bits)
if ((status = inet_pton(AF_INET, dst_ip, &(packet.iphdr.ip_dst))) != 1) {
perror("inet_pton, dst_ip");
exit(EXIT_FAILURE);
}
packet.iphdr.ip_sum = 1;
packet.iphdr.ip_sum = checksum((uint16_t *)&packet.iphdr, IP4_HDRLEN);
// TCP header
if (src_port == 0) {
packet.tcphdr.th_sport = generate_rand(65535.0);
} else {
packet.tcphdr.th_sport = src_port;
}
if (dst_port == 0) {
packet.tcphdr.th_dport = generate_rand(65535.0);
} else {
packet.tcphdr.th_dport = htons(dst_port);
}
packet.tcphdr.th_seq = htonl(seq); //SEQ
packet.tcphdr.th_ack = htonl(ack); //ACK - 0 for first packet
packet.tcphdr.th_x2 = 0; //Reserved
packet.tcphdr.th_off = TCP_HDRLEN / 4; //Offset
// Flags (8 bits)
if(flags == PSHACK){
tcp_flags[0] = 0; //FIN
tcp_flags[1] = 0; //SYN
tcp_flags[3] = 1; //PSH
tcp_flags[4] = 1; //ACK
tcp_flags[2] = 0; //RST
}else if(flags == SYNACK){
tcp_flags[0] = 0; //FIN
tcp_flags[1] = 1; //SYN
tcp_flags[3] = 0; //PSH
tcp_flags[4] = 1; //ACK
tcp_flags[2] = 0; //RST
}else if(flags == FINACK){
tcp_flags[0] = 1; //FIN
tcp_flags[1] = 0; //SYN
tcp_flags[3] = 0; //PSH
tcp_flags[4] = 1; //ACK
tcp_flags[2] = 0; //RST
}else if(flags == FIN){
tcp_flags[0] = 1; //FIN
tcp_flags[1] = 0; //SYN
tcp_flags[3] = 0; //PSH
tcp_flags[4] = 0; //ACK
tcp_flags[2] = 0; //RST
} else if(flags == SYN){
tcp_flags[0] = 0; //FIN
tcp_flags[1] = 1; //SYN
tcp_flags[3] = 0; //PSH
tcp_flags[4] = 0; //ACK
tcp_flags[2] = 0; //RST
}else if(flags == ACK){
tcp_flags[0] = 0; //FIN
tcp_flags[1] = 0; //SYN
tcp_flags[3] = 0; //PSH
tcp_flags[4] = 1; //ACK
tcp_flags[2] = 0; //RST
}else if(flags == RST){
tcp_flags[0] = 0; //FIN
tcp_flags[1] = 0; //SYN
tcp_flags[3] = 0; //PSH
tcp_flags[4] = 0; //ACK
tcp_flags[2] = 1; //RST
}
tcp_flags[5] = 0; //URG
tcp_flags[6] = 0; //ECE
tcp_flags[7] = 0; //CWR
packet.tcphdr.th_flags = 0;
for (int i = 0; i < 8; i++) {
packet.tcphdr.th_flags += (tcp_flags[i] << i);
}
packet.tcphdr.th_win = htons(64240); //Window size
packet.tcphdr.th_urp = htons(0); //Urgent Pointer
//memset(packet.payload, 0, sizeof(packet.payload));
if(data != NULL){
sprintf (packet.payload, "%s", data);
payloadlen = strlen(packet.payload);
}
//payloadlen = strlen(packet.payload);
packet.tcphdr.th_sum = tcp4_checksum(packet.iphdr, packet.tcphdr, (uint8_t *) packet.payload, payloadlen);
memset(&sin, 0, sizeof(struct sockaddr_in));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = packet.iphdr.ip_dst.s_addr;
if ((sending_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
perror("socket() failed ");
exit(EXIT_FAILURE);
}
if (setsockopt(sending_socket, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) {
perror("setsockopt() failed to set IP_HDRINCL ");
exit(EXIT_FAILURE);
}
if (setsockopt(sending_socket, SOL_SOCKET, SO_BINDTODEVICE, &interface,sizeof(interface)) < 0) {
perror("setsockopt() failed to bind to interface ");
exit(EXIT_FAILURE);
}
if (sendto(sending_socket, &packet, IP4_HDRLEN + TCP_HDRLEN + payloadlen, 0, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
perror("sendto() failed ");
exit(EXIT_FAILURE);
}
close(sending_socket);
// Free allocated memory.
free(ip_flags);
free(tcp_flags);
}
服务器代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <signal.h>
#define PORT "8045"
#define MAXCONNECTIONS 1024
int main(void){
int sockfd, new_fd,rv, yes =1;
struct addrinfo hints, *servinfo, *p;
struct sockaddr_storage their_addr;
socklen_t sin_size;
struct sigaction sa;
char s[INET6_ADDRSTRLEN];
hints = set_hints(AF_UNSPEC, SOCK_STREAM, AI_PASSIVE);
if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,p->ai_protocol)) == -1) {
perror("server: socket");
continue;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(int)) == -1) {
perror("setsockopt");
exit(1);
}
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("server: bind");
continue;
}
break;
}
freeaddrinfo(servinfo);
if (listen(sockfd, MAXCONNECTIONS) == -1) {
perror("listen");
exit(1);
}
printf("server: waiting for connections...\n");
sin_size = sizeof their_addr;
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
if (new_fd == -1) {
perror("accept");
}
inet_ntop(their_addr.ss_family,get_in_addr((struct sockaddr *)&their_addr), s, sizeof s);
printf("server: got connection from %s\n", s);
while(1) {
char data[1024];
//recv_normal_tcp_packet(new_fd, data, sizeof(data));
int bytes_receieved = recv(new_fd, data, sizeof(data),0);
printf("Received: %s from %s\n",data, s);
send_normal_tcp_packet(new_fd, data, bytes_receieved);
}
close(new_fd);
close(sockfd);
return 0;
}
最佳答案
您的客户端未正确确认(从服务器)接收到的数据。
现在看来,#6 数据包包含来自服务器的数据。数据包 #7 在 200 毫秒后重新传输,因为客户端确认的速度不够快。这是小问题。
主要问题在数据包 #8 中:客户端尝试确认序列号 321910546。因此服务器可能会忽略它。在这种情况下,正确的数字应该是 6 (seq 1 + len 5)。
因此服务器多次尝试重新传输回显,因为它没有收到有效的确认。
关于c - 原始 TCP 套接字在发送初始数据后接收恒定的 PSH、ACK 数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55115458/
当需要将原始类型转换为字符串时,例如传递给需要字符串的方法时,基本上有两种选择。 以int为例,给出: int i; 我们可以执行以下操作之一: someStringMethod(Integer.to
我有一个位置估计数据库,并且想要计算每月的内核利用率分布。我可以使用 R 中的 adehabitat 包来完成此操作,但我想使用引导数据库中的样本来估计这些值的 95% 置信区间。今天我一直在尝试引导
我希望使用 FTP 编写大型机作业流。为此,我可以通过 FTP 连接到大型机并运行以下命令: QUOTE TYPE E QUOTE SITE FILETYPE=JES PUT myjob.jcl 那么
我是 WPF 的新手。 目前,我正在为名为“LabeledTextbox”的表单元素制作一个用户控件,其中包含一个标签、一个文本框和一个用于错误消息的文本 block 。 当使用代码添加错误消息时,我
我们正在使用 SignalR(原始版本,而不是 Core 版本)并注意到一些无法解释的行为。我们的情况如下: 我们有一个通过 GenericCommand() 方法接受命令的集线器(见下文)。 这些命
使用 requests module 时,有没有办法打印原始 HTTP 请求? 我不只想要标题,我想要请求行、标题和内容打印输出。是否可以看到最终由 HTTP 请求构造的内容? 最佳答案 Since
与直接访问现有本地磁盘或分区的物理磁盘相比,虚拟磁盘为文件存储提供更好的可移植性和效率。VMware有三种不同的磁盘类型:原始磁盘、厚磁盘和精简磁盘,它们各自分配不同的存储空间。 VMware
我有一个用一些颜色着色器等创建的门。 前段时间我拖着门,它问我该怎么办时,我选择了变体。但现在我决定选择创建原始预制件和门颜色,或者着色器变成粉红色。 这是资源中原始预制件和变体的屏幕截图。 粉红色的
我想呈现原始翻译,所以我决定在 Twig 模板中使用“原始”选项。但它不起作用。例子: {{ form_label(form.sfGuardUserProfile.roules_acceptance)
是否可以在sqlite中制作类似的东西? FOREIGN KEY(TypeCode, 'ARawValue', IdServeur) REFERENCES OTHERTABLE(TypeCode, T
这个问题是一个更具体问题的一般版本 asked here .但是,这些答案无法使用。 问题: geoIP数据的原始来源是什么? 许多网站会告诉我我的 IP 在哪里,但它们似乎都在使用来自不到 5 家公
对于Openshift:如何基于Wildfly创建docker镜像? 这是使用的Dockerfile: FROM openshift/wildfly-101-centos7 # Install exa
结果是 127 double middle = 255 / 2 虽然这产生了 127.5 Double middle = 255 / 2 同时这也会产生 127.5 double middle = (
在此处下载带有已编译可执行文件的源代码(大小:161 KB(165,230 字节)):http://www.eyeClaxton.com/download/delphi/ColorSwap.zip 原
以下几行是我需要在 lua 中使用的任意正则表达式。 ['\";=] !^(?:(?:[a-z]{3,10}\s+(?:\w{3,7}?://[\w\-\./]*(?::\d+)?)?/[^?#]*(
这个问题是一个更具体问题的一般版本 asked here .但是,这些答案无法使用。 问题: geoIP数据的原始来源是什么? 许多网站会告诉我我的 IP 在哪里,但它们似乎都在使用来自不到 5 家公
我正在使用GoLang做服务器api,试图管理和回答所发出的请求。使用net/http和github.com/gorilla/mux。 收到请求时,我使用以下结构创建响应: type Response
tl; dr:我认为我的 static_vector 有未定义的行为,但我找不到它。 这个问题是在 Microsoft Visual C++ 17 上。我有这个简单且未完成的 static_vecto
我试图找到原始 Awk (a/k/a One True Awk) 源代码的“历史”版本。我找到了 Kernighan's occasionally-updated site ,它似乎总是链接到最新版本
我在 python 中使用原始 IPv6 套接字时遇到一些问题。我通过以下方式连接: if self._socket != None: # Close out old sock
我是一名优秀的程序员,十分优秀!