Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C中检查服务器端是否建立了连接_C_Linux - Fatal编程技术网

如何在C中检查服务器端是否建立了连接

如何在C中检查服务器端是否建立了连接,c,linux,C,Linux,我已经在服务器端使用C为聊天客户端编写了以下代码。但是,在while循环中,我需要检查客户端是否已退出程序,即与客户端的连接是否丢失。请告诉我怎样才能写出这样的代码 #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h>

我已经在服务器端使用C为聊天客户端编写了以下代码。但是,在while循环中,我需要检查客户端是否已退出程序,即与客户端的连接是否丢失。请告诉我怎样才能写出这样的代码

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <time.h>
int main()
{
int sock, connected, bytes_recieved , true = 1, pid;  
char send_data [1024] , recv_data[1024];     
struct sockaddr_in server_addr,client_addr;    
int sin_size;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
    perror("Socket");
    exit(1);
}
if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&true,sizeof(int)) == -1)
{
    perror("Setsockopt");
    exit(1);
}
server_addr.sin_family = AF_INET;         
server_addr.sin_port = htons(3128);     
server_addr.sin_addr.s_addr = INADDR_ANY; 
bzero(&(server_addr.sin_zero),8); 
if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
{
    perror("Unable to bind");
    exit(1);
}
if (listen(sock, 5) == -1)
{
    perror("Listen");
    exit(1);
}
printf("\nTCPServer Waiting for client on port 3128");
fflush(stdout);
FILE *log;
log = fopen("time.log", "a");
time_t t;
while(1)
{  
    sin_size = sizeof(struct sockaddr_in);
    connected = accept(sock, (struct sockaddr *)&client_addr,&sin_size);
    printf("\n I got a connection from (%s , %d)", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
    fflush(stdout);           
    int pid=fork();
    while(1)
    {       
        if(pid == 0)
        {
            usleep(1000000);
            time(&t);
            send(connected, ctime(&t),30, 0);
        }
        else
        {
            bytes_recieved = recv(connected,recv_data,1024,0);
            recv_data[bytes_recieved] = '\0';
            fputs(recv_data, log);
            fputs("Time: ", log);
            time(&t);
            fputs(ctime(&t), log);
        }
        fflush(log);
    }   
    }   
fclose(log);
close(sock);
return 0;
} 
编译时,它运行正常,但在运行时,它会给出以下错误输出:

*** glibc detected *** ./server: double free or corruption (!prev): 0x09936008 ***
======= Backtrace: =========
/lib/i686/cmov/libc.so.6(+0x6b381)[0xb7659381]
/lib/i686/cmov/libc.so.6(+0x6cbd8)[0xb765abd8]
/lib/i686/cmov/libc.so.6(cfree+0x6d)[0xb765dcbd]
/lib/i686/cmov/libc.so.6(fclose+0x14a)[0xb764982a]
./server[0x8048c21]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb7604ca6]
./server[0x8048861]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:01 133298     /home/harikrishnan/server/server
08049000-0804a000 rw-p 00000000 08:01 133298     /home/harikrishnan/server/server
09936000-09957000 rw-p 00000000 00:00 0          [heap]
b7400000-b7421000 rw-p 00000000 00:00 0 
b7421000-b7500000 ---p 00000000 00:00 0 
b75bf000-b75dc000 r-xp 00000000 08:01 3653635    /lib/libgcc_s.so.1
b75dc000-b75dd000 rw-p 0001c000 08:01 3653635    /lib/libgcc_s.so.1
b75ed000-b75ee000 rw-p 00000000 00:00 0 
b75ee000-b772e000 r-xp 00000000 08:01 3670051    /lib/i686/cmov/libc-2.11.3.so
b772e000-b772f000 ---p 00140000 08:01 3670051    /lib/i686/cmov/libc-2.11.3.so
b772f000-b7731000 r--p 00140000 08:01 3670051    /lib/i686/cmov/libc-2.11.3.so
b7731000-b7732000 rw-p 00142000 08:01 3670051    /lib/i686/cmov/libc-2.11.3.so
b7732000-b7735000 rw-p 00000000 00:00 0 
b7744000-b7747000 rw-p 00000000 00:00 0 
b7747000-b7748000 r-xp 00000000 00:00 0          [vdso]
b7748000-b7763000 r-xp 00000000 08:01 3654097    /lib/ld-2.11.3.so
b7763000-b7764000 r--p 0001b000 08:01 3654097    /lib/ld-2.11.3.so
b7764000-b7765000 rw-p 0001c000 08:01 3654097    /lib/ld-2.11.3.so
bfd94000-bfda9000 rw-p 00000000 00:00 0          [stack]
*** glibc detected *** ./server: double free or corruption (!prev): 0x09936008 ***
======= Backtrace: =========
/lib/i686/cmov/libc.so.6(+0x6b381)[0xb7659381]
/lib/i686/cmov/libc.so.6(+0x6cbd8)[0xb765abd8]
/lib/i686/cmov/libc.so.6(cfree+0x6d)[0xb765dcbd]
/lib/i686/cmov/libc.so.6(fclose+0x14a)[0xb764982a]
./server[0x8048c21]
/lib/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb7604ca6]
./server[0x8048861]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:01 133298     /home/harikrishnan/server/server
08049000-0804a000 rw-p 00000000 08:01 133298     /home/harikrishnan/server/server
09936000-09957000 rw-p 00000000 00:00 0          [heap]
b7400000-b7421000 rw-p 00000000 00:00 0 
b7421000-b7500000 ---p 00000000 00:00 0 
b75bf000-b75dc000 r-xp 00000000 08:01 3653635    /lib/libgcc_s.so.1
b75dc000-b75dd000 rw-p 0001c000 08:01 3653635    /lib/libgcc_s.so.1
b75ed000-b75ee000 rw-p 00000000 00:00 0 
b75ee000-b772e000 r-xp 00000000 08:01 3670051    /lib/i686/cmov/libc-2.11.3.so
b772e000-b772f000 ---p 00140000 08:01 3670051    /lib/i686/cmov/libc-2.11.3.so
b772f000-b7731000 r--p 00140000 08:01 3670051    /lib/i686/cmov/libc-2.11.3.so
b7731000-b7732000 rw-p 00142000 08:01 3670051    /lib/i686/cmov/libc-2.11.3.so
b7732000-b7735000 rw-p 00000000 00:00 0 
b7744000-b7747000 rw-p 00000000 00:00 0 
b7747000-b7748000 r-xp 00000000 00:00 0          [vdso]
b7748000-b7763000 r-xp 00000000 08:01 3654097    /lib/ld-2.11.3.so
b7763000-b7764000 r--p 0001b000 08:01 3654097    /lib/ld-2.11.3.so
b7764000-b7765000 rw-p 0001c000 08:01 3654097    /lib/ld-2.11.3.so
bfd94000-bfda9000 rw-p 00000000 00:00 0          [stack]
Aborted

知道实际的问题是什么吗?

如果发送返回套接字错误,这意味着套接字关闭或连接丢失

那就这么做吧

if (send(connected, ctime(&t),30, 0) == SOCKET_ERROR)
 {
   // blablabla
 }
客户端关闭连接后,
recv()
将立即返回
0
<如果尝试从套接字获取数据时出现任何错误,将返回代码>-1

有关更多信息,请参阅

所以把你的代码改成

   int conn_closed = 0;

   bytes_recieved = recv(connected,recv_data,1024,0);
   switch (bytes_recieved) {
   case 0:
         /* connection closed by client */
         close(connected);
         conn_closed = 1;
         break;
   case -1:
         /* error on socket */
         /* TODO: insert error handling code */
         if (errno == EAGAIN || errno == EINTR) {
            /* safe to retry */
            conn_closed = 0;
         } else {
            close(connected)
            conn_closed = 1;
         }
         break;
   default:
        recv_data[bytes_recieved] = '\0';
        fputs(recv_data, log);
        fputs("Time: ", log);
        time(&t);
        fputs(ctime(&t), log);
        conn_closed = 0;
        break;
   }
   /* break out of the loop if conn_closed */
   if (conn_closed)
       break;
不要忘记检查
send()
的返回值,查看发送数据时是否发生错误

更新:为
EAGAIN
EINTR
添加了错误处理代码

第二次更新:

为了完整起见,以下是您应该添加的发送代码

if (send(connected, ctime(&t),30, 0) == -1)
{
    if (errno == EAGAIN || errno == EINTR) {
       /* retry to send */
    }
    close(connected);
    break;
}

在您的情况下,一个小建议是,不要给出检查连接的“如果”条件,而要在“while”(而不是“while(1)”,给出条件的“while”中执行相同的操作。

您需要等待输入、关闭事件等。您在每次迭代中都会丢失(日志)。只有第一个才能成功。
server.c:80:error:“SOCKET\u error”未声明(首次用于此函数)
这是我编译上述代码时遇到的错误。@JohnSmith:SOCKET\u error在linux上没有定义,因此检查应该是
if(send()=-1)
,然后计算
errno
的错误。对不起,我的错了,刚刚看到标签…>我认为真的不需要那个开关。如果上述代码能够正常工作,那么以下代码也将正常工作:int conn_closed;接收的字节数=recv(已连接,recv_数据,1024,0);如果(bytes_received==0 | | bytes_received===1){//statement}btw,您可能还希望在出现错误时关闭套接字,而不仅仅是断开连接。您应该处理
-1
的返回值,并检查
errno
,因为这可能是您刚刚被信号中断的情况,并且可以安全地重试。这就是我选择开关()的原因。
if (send(connected, ctime(&t),30, 0) == -1)
{
    if (errno == EAGAIN || errno == EINTR) {
       /* retry to send */
    }
    close(connected);
    break;
}