【问题标题】:Bad file descriptor error while creating a concurrent server in a client-server app (UDP)在客户端-服务器应用程序 (UDP) 中创建并发服务器时出现错误的文件描述符错误
【发布时间】:2011-04-11 21:21:41
【问题描述】:

我正在使用带有并发服务器的 udp 制作客户端-服务器应用程序,但在将信息发送到服务器时遇到了一些问题。

这是服务器的代码:

#define SERV_UDP_PORT   6777

int main() {

int sockfd, newsockfd, clilen, n, pid_hijo;
struct sockaddr_in cli_addr, serv_addr ;
char host_name[200], buffer[1024];

if ((sockfd = socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP)) < 0){
   perror("server: can't open datagram socket");
   exit(-1);
} /* if */


serv_addr.sin_family = AF_INET ;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY) ;
serv_addr.sin_port = htons(SERV_UDP_PORT);

if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) <0) {
    perror("server: can't bind local address") ;
    exit(-1);
} /* if */


for (;;) {
    // Create the new process for the concurrente server
    if ((pid_hijo=fork()) == 0) {
        servidor_hijo(sockfd);
        close(sockfd);
        exit(0);
    }
    else {
        close(sockfd);
        while (wait((int *)0) != pid_hijo);
    }
}
}

int servidor_hijo(int sockfd) {

int n, clilen;
char buffer[1024];
struct sockaddr_in cli_addr;


// Inicializamos los buffers
clilen = sizeof(cli_addr) ;
bzero((char *)&cli_addr,clilen); /* debe inicializarse cli_addr antes del recvfrom */
bzero(buffer, sizeof(buffer));


if ((n=recvfrom(sockfd, buffer, sizeof(buffer),0, (struct sockaddr *)&cli_addr,&clilen)) <0) {
    perror("secho: error en funcion recvfrom");
    exit(-1);
} /* if */


printf("\n\n%s (%d bytes)\n",buffer,n);

if ((n=sendto(sockfd, buffer, strlen(buffer),0, (struct sockaddr *)&cli_addr,clilen)) <0) {
    perror("secho: Error en funcion sendto");
    exit(-1);
}
}

这是客户端的代码

/* Cliente de ECO sobre UDP*/

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define SERV_UDP_PORT   6777

main() {
    int sockfd, n, clilen;
    struct sockaddr_in serv_addr, cli_addr ;
    char serv_host_addr[30], buffer[1024];

    printf("Dirección IP del servidor (a.b.c.d) => ");
    gets(serv_host_addr);

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        perror("client: can't open datagram socket") ;
        return -1;
    }


    bzero((char *)&cli_addr,sizeof(cli_addr)); /* puerto cero */
    cli_addr.sin_family = AF_INET ;

    if (bind(sockfd, (struct sockaddr *) &cli_addr,sizeof(cli_addr)) < 0) {
        perror("client: can't bind a port");
        exit(-1);
    } /* if */

    serv_addr.sin_family = AF_INET ;
    inet_pton(AF_INET,serv_host_addr,&serv_addr.sin_addr);
    serv_addr.sin_port = htons(SERV_UDP_PORT) ;


    printf("Bienvenido al Servicio de ECO ==> "); 
    gets(buffer);

    clilen=sizeof(serv_addr);
    if ((n=sendto(sockfd, buffer,strlen(buffer),0, (struct sockaddr *)&serv_addr,clilen)) <0) {
        perror("cecho: error en funcion sendto");
        exit(-1);
    } /* if */

    printf("cecho: envie %d bytes\n",n);

    bzero(buffer,sizeof(buffer));
    clilen = sizeof(serv_addr);

    if ((n=recvfrom(sockfd,buffer,sizeof(buffer),0, (struct sockaddr*)&serv_addr,&clilen)) < 0) {
        perror("cecho: error en funcion recvfrom");
        exit(-1);
    } /* if */
    printf("ECO> %s\n",buffer);
    close(sockfd);
    }

servidor_hijo 函数使服务器并发响应不同的请求...

问题是......当我执行客户端应用程序时,它会将数据包发送到服务器应用程序,但服务器不会发送响应并在屏幕上打印一条错误消息,告诉您“文件错误”描述符错误”。

你能帮我解决这个问题吗?

谢谢大家!!

【问题讨论】:

  • 首先你必须打开套接字:udp_socket = socket(AF_INET, SOCK_DGRAM, 0); 然后尝试找出错误文件描述符错误是在哪一点产生的。它在 servidor_hijo 函数内吗?具体在哪里?
  • 我已经做到了... :( 不知道怎么回事 :(
  • recvfrom函数产生错误。
  • 无论发生什么,您都应该将exit(-1) 替换为exit(EXIT_FAILURE)。在许多 Unix 系统上,shell 中返回状态码的可能值范围是 0-255,其中 0 表示成功,1 是典型的失败值(您可能会发现 EXIT_FAILURE 表示 1)。使用 -1 退出会溢出,你的 shell 会看到返回码为 255,这只是令人困惑。

标签: c sockets unix


【解决方案1】:

试试这个:(否则我必须阅读 fork 和 fd's)

第

马里奥

【讨论】:

  • 谢谢!不过要小心,我不确定(并且还没有找到一个快速的答案)这是否真的是一个好主意。在 fork 中,fd 是 dup()'ed,所以它也应该可以工作。
【解决方案2】:

您正在调用 bind(),然后是 fork()。 您不能将两个进程和两个套接字绑定到同一个端口。

我建议你收到数据包,然后 fork() 来处理它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-24
    • 1970-01-01
    • 1970-01-01
    • 2023-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-21
    相关资源
    最近更新 更多