C语言 BSD套接字:为什么`send`仍然返回成功,即使我在服务器上丢弃数据包?[副本]

8yoxcaq7  于 2023-08-03  发布在  其他
关注(0)|答案(1)|浏览(79)

此问题已在此处有答案

send() function behavior when link goes down in a TCP connection(1个答案)
9天前关闭。
下面是我的测试代码:

#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
int set_keep_alive(int sockfd) {
    int optval = 1;
    if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &optval, sizeof(optval)) == -1) {
        perror("setsockopt");
        close(sockfd);
        return -1;
    }
    int flags = 6;
         if (setsockopt(sockfd , IPPROTO_TCP, TCP_KEEPIDLE, (void *)&flags, sizeof(flags)))
        {
            return -1;
         };

         flags = 3;
         if (setsockopt(sockfd , IPPROTO_TCP,  TCP_KEEPINTVL, (void *)&flags, sizeof(flags)))
         {
            return -1;
         };

         flags = 3;
         if (setsockopt(sockfd , IPPROTO_TCP, TCP_KEEPCNT, (void *)&flags, sizeof(flags)))
         {
            return -1;
        };
    return 0;
}
int main(int argc, char **argv) {
    if (argc != 3) {
        fprintf(stderr, "usage: %s <ip> <port>\n", argv[0]);
        return -1;
    }
    char const *IP = argv[1];
    int PORT = atoi(argv[2]);

    int fd = socket(AF_INET, SOCK_STREAM, 0);
    set_keep_alive(fd);
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(PORT);
    inet_pton(AF_INET, IP, &addr.sin_addr);
    int ret;
    ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
    if (ret < 0) {
        printf("connect failed, ret = %d, errno=%d\n", ret, errno);
        perror("");
        return 1;
    }

    for(int i = 0;;i++, sleep(1)) {
        char buf[100];
        sprintf(buf, "hello%d", i%10);
        int ret = send(fd, buf, strlen(buf), MSG_CONFIRM);
        printf("%d,write ret = %d\n", i, ret);
    }
    close(fd);
    return 0;
}

字符串
假设它被称为client.c

  1. gcc client.c得到a.out
    1.在服务器中,使用nc -l -p <PORT>
  2. ./a.out <Server IP> <PORT>:将打印
0,write ret = 6
1,write ret = 6
2,write ret = 6
3,write ret = 6
4,write ret = 6
5,write ret = 6
6,write ret = 6
....


1.在服务器中,有一个名为port-close.sh的shell脚本,它将新传入的数据包丢弃到端口

#!/bin/sh
iptables -I INPUT -p tcp --dport $1 -j DROP


如果我在客户端运行./port-close.sh <PORT>,在我等待15秒(保持活动时间)之后,仍然打印ret = 6,这意味着成功。

请注意更换和配置

okxuctiv

okxuctiv1#

成功发送数据并不意味着必须接收数据。您阻止了数据从TCP层进入网络。您没有阻止它从应用程序发送到TCP层,这是成功的发送。

相关问题