远程登录我的套接字侦听端口正在关闭套接字

Posted

技术标签:

【中文标题】远程登录我的套接字侦听端口正在关闭套接字【英文标题】:telnetting my socket listening port is closing socket 【发布时间】:2013-01-04 10:19:41 【问题描述】:

我是这个网站的新手,所以如果之前已经回答过这个问题,我会提前道歉,尽管我在向这里的每个人开放之前已经搜索过它。

我在我的一个 C 程序中使用套接字编程。它具有服务器和客户端模块,其中服务器和客户端可以双向通信。程序运行良好,因为我能够双向发送文件和消息。 我的服务器程序正在使用端口3873,我已经通过netstat -anp | grep 3873确认了这一点

我观察到套接字的一种奇怪行为,尤其是当我尝试使用浏览器连接套接字时,例如 http://localhost:3873telnet localhost 3873。它立即关闭套接字和随后的'netstat -anp | grep 3873' 输出确认 localhost 不再监听端口 3873

如果有人能阐明这种行为,我将不胜感激。这是预期的行为吗?

这是服务器代码的相关部分:主程序启动一个专用线程并调用startFileServerMT,随后调用handleClient为每个连接到套接字上的服务器的客户端提供服务

int handleClient(void *ptr)
    DEBUG("Inside the %s %s() \n",__FILE__,__func__);
    int  connectSOCKET;
    connectSOCKET = (int ) ptr;
    char recvBUFF[4096],sendBUFF[4096];
    char *filename;
    FILE * recvFILE;
    char *header[4096];    
    while(1)
        if( recv(connectSOCKET, recvBUFF, sizeof(recvBUFF), 0) > 0)
            if(!strncmp(recvBUFF,"FBEGIN",6))                           
                recvBUFF[strlen(recvBUFF) - 2] = 0;
                parseArgs(header,recvBUFF);                                 
                filename = (char*) strngDup(header[1]);                                
                DEBUG("  About to receive file: %s\n", filename);
            

            char *rfile = ALLOC(sizeof(char) * (strlen(This.uploadDIR) + strlen(filename) + 35));
            strcpy(rfile,This.uploadDIR);

            if (strngLastChar(rfile) == '/')
                strcat(rfile,filename);
            else
                strcat(rfile,"/");
                strcat(rfile,filename);        
            
            DEBUG("  Absolute file is : %s\n", rfile);
            recvBUFF[0] = 0;
            if ((recvFILE = fopen (rfile,"w" )) == NULL)
                LogError("Server could not create file %s on the shared location %s.\n",filename,This.uploadDIR);                
            else
                bzero(recvBUFF,4096);
                int fr_block_sz, write_sz;
                while((fr_block_sz = recv(connectSOCKET, recvBUFF, 512, 0)) > 0 )
                    write_sz = fwrite (recvBUFF , sizeof(recvBUFF[0]) , fr_block_sz , recvFILE );
                    DEBUG("  Received buffer is : %s\n", recvBUFF);
                    if(write_sz < fr_block_sz)
                        LogError("Failed writing file %s on the Server shared location.\n",filename);
                        break;
                    
                    bzero(recvBUFF,4096);
                    recvBUFF[0] = 0;
                    if(write_sz == 0 || fr_block_sz != 512 )   
                        break;
                    
                

                if(fr_block_sz < 0)
                    if(errno == EAGAIN)
                        LogError("Server collection file %s receive timed out.\n",filename);
                    else
                        LogError("Failed file %s transfer due to error %d\n",filename,errno);
                        fclose(recvFILE);
                        FREE(rfile);
                        // Start - Following code send failed status to client    
                        sprintf(sendBUFF,"FSTATUS:FAILED\r\n");    

                        if (send(connectSOCKET, sendBUFF, sizeof(sendBUFF), 0) >= 0)
                            DEBUG("File transfer status for file %s sent\n",filename);
                        else
                            DEBUG("Failed sending transfer status for file %s\n",filename);
                            return FALSE;
                         

                        // End

                        close(connectSOCKET);
                        return FALSE;
                    
                
                    DEBUG("File %s received on OM Server successfully.\n",filename);

                    // Start - Following code send failed status to client    
                    sprintf(sendBUFF,"FSTATUS:SUCCESS\r\n");    

                    if (send(connectSOCKET, sendBUFF, sizeof(sendBUFF), 0) >= 0)
                        DEBUG("File transfer status for file %s sent\n",filename);
                    else
                        DEBUG("Failed sending transfer status for file %s\n",filename);
                        return FALSE;
                     
                    // End

                    fclose(recvFILE);
                    updateTargets(rfile);
                    FREE(rfile);
                    close(connectSOCKET);
                    break;

            
        
        else 
            LogInfo("Client dropped connection\n");
        

/** End*/  
        return TRUE;
        


int startFileServerMT()
    DEBUG("Inside %s %s() \n",__FILE__,__func__);

    int listenSOCKET, connectSOCKET[512],thread_status;
    int socketINDEX = 0;

    pthread_t clientFileThread[512];
    socklen_t clientADDRESSLENGTH[512];
    struct sockaddr_in clientADDRESS[512], serverADDRESS;    


    if((listenSOCKET = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
        LogAbortError("File server could not create socket.\n");
        close(listenSOCKET);
        return FALSE;        
    

    serverADDRESS.sin_family = AF_INET;
    serverADDRESS.sin_addr.s_addr = htonl(INADDR_ANY);  
    serverADDRESS.sin_port = htons(This.serverport);

    if (bind(listenSOCKET, (struct sockaddr *) &serverADDRESS, sizeof(serverADDRESS)) < 0) 
        LogAbortError("File server could not bind socket and will stop server now.\n");
        close(listenSOCKET);
        This.stopped = TRUE;
        return FALSE;
    

    if(listen(listenSOCKET, 5) == -1)
        LogAbortError("Server failed to listen on port %d and will stop server now.\n",This.serverport);
        close(listenSOCKET);
        This.stopped = TRUE;
        return FALSE;        
    else
        LogInfo("Server listening on port %d successfully.\n",This.serverport);        
    

    clientADDRESSLENGTH[socketINDEX] = sizeof(clientADDRESS[socketINDEX]);

    while(TRUE)   
       // DEBUG("  Inside the file server main loop index[%d].\n",socketINDEX);

        connectSOCKET[socketINDEX] = accept(listenSOCKET, (struct sockaddr *) &clientADDRESS[socketINDEX], &clientADDRESSLENGTH[socketINDEX]);
            if(connectSOCKET[socketINDEX] < 0)
            LogError("Server could not accept connection.\n");
            close(listenSOCKET);
            return FALSE;
        else
            DEBUG("  Another client connected to server socket.\n");

        ThreadCreateDetached( &clientFileThread[socketINDEX], handleClient, connectSOCKET[socketINDEX]);     

        if(socketINDEX=512) 
            socketINDEX = 0;
         else  
            socketINDEX++;
                                          

        if (This.stopped == TRUE)
            close(listenSOCKET);
            return TRUE;
              
/** End*/  
//        return TRUE;
    

    close(listenSOCKET);
    return TRUE;


【问题讨论】:

听起来您的服务器程序正在崩溃。你检查过服务器发生了什么吗? 他希望我们在不发布他的源代码的情况下调试他的服务器代码.... Joachim 已经猜对了 ;-) 查看我前段时间上传的这个用 C 语言快速联网的教程,以了解类似的问题。 scribd.com/doc/120274805/QGNP希望这会有所帮助:) HTTP 和 telnet 协议通过您的代码可能不支持的连接发送数据。您需要针对此类无法识别的数据来证明您的代码(例如,通过丢弃它并记录错误)。 recvBUFF[strlen(recvBUFF) - 2] = 0; 让我不寒而栗。我知道代码在使用前加载了缓冲区的 memset/bzero,但这不是 IMnsvHO 的方法。请使用从 read() write() recv() send() 获得的返回值 【参考方案1】:

这是您的问题 - 或者至少是您的问题的一部分。这不仅是一个错误(connectSOCKET 接受从 0-511 包含的索引,所以如果你在 512,你已经写过了 connectSOCKET 数组的末尾),但你确实这样做了分配而不是比较:

    if(socketINDEX=512)  // Error: you are *setting* socketINDEX to 512, 
                          // then immediately *resetting* it back to 0. So
                          // every new connection overrides the existing
                          // socket.
        socketINDEX = 0;
     else  
        socketINDEX++;
    

作为旁注,你真的应该重构你的代码并尝试清理它。

【讨论】:

感谢您的观察 Nik,我已更正此问题并收集了有关服务器崩溃的更多信息,发现一个无效指针导致服务器崩溃,我现在已更正。 如果recvBUFF 为nto FBEGIN,则文件名未初始化并且rfile 的内存分配失败。 ` if(!strncmp(recvBUFF,"FBEGIN",6)) recvBUFF[strlen(recvBUFF) - 2] = 0; parseArgs(标题,recvBUFF);文件名 = (char) strngDup(header[1]); DEBUG("即将接收文件: %s\n", filename); char *rfile = ALLOC(sizeof(char) * (strlen(This.uploadDIR) + strlen(filename) + 35));`

以上是关于远程登录我的套接字侦听端口正在关闭套接字的主要内容,如果未能解决你的问题,请参考以下文章

无法远程登录到 php 套接字代码

UDP Socket:一个现有的连接被远程主机强行关闭

是否是侦听服务结构远程端点的单个线程

C# TCP 在同一个本地端口上侦听和连接

C - 为啥我不能从本地主机外部访问我的服务器?

如何使用 Perl 通过 TCP 和 UDP 连接到远程机器?