在socket上发送时错误的文件描述符错误

时间:2018-01-22 14:20:08

标签: c sockets tcpsocket

我正在尝试将数据从服务器子进程发送到客户端。 我在ids [0]中存储第一个客户端fd,在ids [1]中存储第一个客户端fd 然后我试图将数据从第一个子进程发送到另一个客户端,反之亦然。

我的文件描述符错误。

//ids are defined at the begining as follows
    int *ids = (int *) mmap(NULL,5*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
//accept is in a for loop...
    mysocket = accept(sock, NULL, NULL);
    printf("\nClient connected ...\n ");
    ids[i]=mysocket;
    i++;
    printf(" socket and id %d %d",mysocket,ids[i-1]);
    int pid = fork();
    if (pid == 0) {
        if (mysocket < 0) {
            perror("Error in accept");
            exit(1);
        }

    do {

        fflush(stdout);
        //clearing the bufffer
        //memset(&buf[0], 0, sizeof(buf));
        //memset(buf, sizeof(buf), '\0');
        //reading message on the socket.
        if(i==1)
        if(send(ids[1], buf, 1024,0)==-1){
            perror("error in i=1");
                    printf("%d %d %d",mysocket,ids[0],ids[1]);
        }

        if(i==2) {
            if(send(ids[0], buf, 1024,0)==-1) {
                perror("error in i=2");
                printf("%d %d %d", mysocket, ids[0], ids[1]);
            }
        }

        if (strcmp(buf, "CLOSE") == 0) {
            close(mysocket);
            break;
        }

    } while (1);

我得到的错误: i = 1中的错误:文件描述符错误 4 4 5

值4和5是fds并且是正确存储的,我没有在任何地方关闭套接字。

1 个答案:

答案 0 :(得分:1)

您的代码格式错误,我希望我能正确理解它。

ids[i]=mysocket;
i++;

如果i0,那么ids[0]现在有效,ids[1]仍然无效(即有一些可能看似有效的任意值,但不是)和{{ 1}}现在是i。使用1,子进入此代码(正确格式化后):

i==1

如您所见,它使用 if(i==1) if(send(ids[1], buf, 1024,0)==-1){ perror("error in i=1"); printf("%d %d %d",mysocket,ids[0],ids[1]); } 。但正如上面send(ids[1]...解释的那样,只有i==1具有有效值,ids[0]中的值无效。因此,ids[1]失败并显示send

我的猜测是你假设在主进程中创建的文件描述符实际上在所有子进程中都有效,因为你试图在子进程和主进程之间使用共享数组(Bad file descriptor): / p>

MAP_SHARED

但这种假设是错误的。文件描述符不会传播到所有子进程中,而只会在fork上传播到新子进程。这意味着您的第一个孩子将只在int *ids = (int *) mmap(NULL,5*sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); 中拥有有效的文件描述符,而第二个孩子在fds[0]fds[0]中都有一个有效的文件描述符。 由于共享数组,第一个子节点将在fds[1]中看到与第二个子节点相同的文件编号这一事实并不意味着此文件编号也与有效(内核中)文件描述符相关联

请注意,在代码中实际记录代码的意图非常有用。这样,其他人可以更好地理解您的代码,所有人(包括您)可以更好地验证意图是否与实现相符。