Admin_Poker 2023-12-26 14:34 采纳率: 75%
浏览 10

`悬赏20`,C语言socket,垃圾CSDN,有的时候没找到答案还收我钱。

问题遇到的现象和发生背景

我使用socket开发一个端口穿透工具,我想将本地的tcp端口转发到公网的服务器上,然后可以开放给其他人访问。
要点: 自己开发,不使用其他成熟工具,小弟只想要知道结果

遇到的现象和发生背景,请写出第一个错误信息

我服务端已经将数据发送到agent端的socket之后,使用select判断readfds中的状态,发现不能读取,我使用控制台printf直接读取内容发现存在内容可以读取,但是select不能获取到读取状态

数据交换函数代码
int example(int server_fd,int internal_fd){
    fd_set readfd,writefd;
    char from_server_buffer[MAXBUFFERLEN]={0};
    char from_internal_buffer[MAXBUFFERLEN]={0};
    int from_server_readlen=0;
    int from_internal_readlen=0;

    FD_ZERO(&readfd);
    FD_ZERO(&writefd);

    FD_SET(server_fd,&readfd);
    FD_SET(internal_fd,&readfd);
    FD_SET(internal_fd,&writefd);
    FD_SET(server_fd,&writefd);
    int selectret=0;
    int maxfd=(server_fd>internal_fd)?server_fd:internal_fd;
    struct timeval timeset;
    timeset.tv_sec=10000;
    timeset.tv_usec=0;
    prinft("server_fd: %d internal_fd: %d maxfd: %d\n",server_fd,internal_fd,maxfd);
    while(1){
        int error=0;
        selectret=select(maxfd+1,&readfd,&writefd,NULL,&timeset);
        if(selectret == -1 && errno == EINTR){
            prinft("select接受错误!!");
            continue;
        }else if (selectret ==0){
            prinft("超时了哦!!");
            continue;
        }
        if(FD_ISSET(server_fd,&readfd)){
            int readlen=0;
            char buffer[4096]={0};
            int error=0;
            while(error!=1){
                readlen=read(server_fd,buffer,MAXBUFFERLEN);
                if(readlen >0){
                    prinft("从server端读取到内容: %s len: %d\n",buffer,readlen);
                }else{
                    error=1;
                }
                if(readlen>0){
                    int ret=write(internal_fd,buffer,readlen);
                    prinft("开始写入 buffer: %s len: %d ret: %d\n",buffer,readlen,ret);
                    memset(buffer,0,4096);
                }else{
                    error=1;
                }
            }
        }else{
            prinft("读取server_Fd未就绪\t");
            int readlen=0;
            char buffer[4096]={0};
            readlen=read(server_fd,buffer,MAXBUFFERLEN);
            prinft("尝试读取的结果: %s\n",buffer);
        }

        if(FD_ISSET(internal_fd,&readfd)){
            char buffer[4096]={0};
            int readlen=read(internal_fd,buffer,MAXBUFFERLEN);
            prinft("从agent端读取到内容: %s len: %d\n",buffer,readlen);
            memcpy(from_internal_buffer,buffer,readlen);
            from_internal_readlen+=readlen;
        }
        if(from_internal_readlen>0){
            int ret=write(server_fd,from_internal_buffer,from_internal_readlen);
            prinft("开始写入 buffer: %s len: %d\n",from_internal_buffer,from_internal_readlen);
            from_internal_readlen-=ret;
            memset(from_internal_buffer,0,4096);
        }
        sleep(1);      //防止重复刷log,影响debug

    }
    return 1;
}

wireshark有流量返回

img

运行结果及详细报错内容

控制台打印log发现存在可读的内容

img

我想要达到的结果

我想要知道FD_ISSET为什么不能判断状态为可读,因为我其他的地方也有这个问题。。包括服务端

源码文件

访问即可下载: https://120.27.210.140:19980/
直接
gcc agent.c -o agent
gcc server.c -p serv
就好了
显示内容

  • 写回答

1条回答 默认 最新

  • mengduoduo_ 2023-12-26 14:53
    关注

    根据你提供的代码和描述,有几个可能导致 FD_ISSET 不能正确判断可读状态的问题。

    1、没有正确对 readfd 和 writefd 进行重新赋值。 在每次循环开始前,你需要重新设置 readfd 和 writefd,因为 select 函数会修改它们的值。可以在每次循环开始前添加以下代码:

    FD_ZERO(&readfd);
    FD_ZERO(&writefd);
    
    FD_SET(server_fd,&readfd);
    FD_SET(internal_fd,&readfd);
    FD_SET(internal_fd,&writefd);
    FD_SET(server_fd,&writefd);
    
    

    2、select 超时时间设置不正确。
    你将 timeset.tv_sec 设置为 10000,这意味着 select 函数将等待 10000 秒后超时。如果你想要一个较短的超时时间,可以将 timeset.tv_sec 设置为一个较小的值,比如 5(5秒)。

    3、可能存在其他错误。
    在你提供的代码中,可能还存在其他错误导致无法正确判断可读状态。你可以检查是否有其他地方修改了 readfd 和 writefd 的值,或者是否存在其他与文件描述符相关的问题。

    另外,你在代码中多次使用了错别字 prinft,应该是 printf。

    评论
    1人已打赏

报告相同问题?

问题事件

  • 创建了问题 12月26日

悬赏问题

  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看