Unix/Linux socket编程的一个问题?

服务端提供一个返回时间的服务,客户端使用telnet去访问

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <time.h>
#include <strings.h>

#define PORTNUM 13000
#define HOSTLEN 256
#define oops(msg) {perror(msg); exit(1);}

int main()
{
    struct sockaddr_in saddr;
    struct hostent *hp;
    char hostname[HOSTLEN];
    int sock_id, sock_fd;
    FILE *sock_fp;
    char *ctime();
    time_t thetime;

    sock_id = socket(PF_INET, SOCK_STREAM, 0);
    if( sock_id == -1 )
        oops("scoket");
    
    bzero((void*)&saddr, sizeof(saddr));

    gethostname(hostname, HOSTLEN);
    hp = gethostbyname(hostname);

    bcopy((void*)hp->h_addr, (void*)&saddr.sin_addr, hp->h_length);
    saddr.sin_port = htons(PORTNUM);
    saddr.sin_family = AF_INET;
    
    if( bind(sock_id, (struct sockaddr*)&saddr, sizeof(saddr)) != 0  )
        oops("bind");

    if( listen(sock_id, 1) != 0 )
        oops("listen");

    while(1) {
        sock_fd = accept(sock_id, NULL, NULL);
        printf("Wow! got a call\n");
        if( sock_fd == -1 )
            oops("accept");
        
        sock_fp = fdopen(sock_id, "w");
        if (sock_fp == NULL)
            oops("fdopen");
        thetime = time(NULL);

        fprintf(sock_fp, "The time here is...");
        fprintf(sock_fp, "%s", ctime(&thetime));
        fclose(sock_fp);
    }
}

运行结果:

deweixudeMBP:socket deweixu$ ./timeserv.out &
[1] 32999
deweixudeMBP:socket deweixu$ hostname
deweixudeMBP.lan
deweixudeMBP:socket deweixu$ telnet deweixudeMBP.lan 13000
Trying 192.168.199.205...
Wow! got a call
Connected to deweixudembp.lan.
Escape character is '^]'.
Wow! got a call
accept: Bad file descriptor
Connection closed by foreign host.
[1]+  Exit 1                  ./timeserv.out
deweixudeMBP:socket deweixu$ 

为什么会 accept: Bad file descriptor ?

阅读 3.3k
2 个回答
    sock_fd = accept(sock_id, NULL, NULL);
    printf("Wow! got a call\n");
    if( sock_fd == -1 )
        oops("accept");
    
    sock_fp = fdopen(sock_id, "w");

sock_fp = fdopen(sock_id, "w");
换成
sock_fp = fdopen(sock_fd, "w");

你给出的程序这句话纯属多余:
sock_fp = fdopen(sock_id, "w");

accept 之后的socket就可以直接读写,不需要用管道命令打开,删了应该就好。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进