2011-04-11 38 views
0

我正在用udp和并发服务器制作客户端 - 服务器应用程序,并且在将信息发送到服务器时遇到一些问题。在客户端 - 服务器应用程序(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是什么使服务器的并发回复不同的请求的代码...

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

你能帮我解决吗?

谢谢大家!

+0

首先,你必须与打开插座: 'UDP_SOCKET =插座(AF_INET,SOCK_DGRAM,0);' 然后试图找到确切时点坏的文件描述符错误正在产生。它在servidor_hijo函数中吗?究竟在哪里? – 2011-04-11 12:40:41

+0

我已经这样做了...... :(不知道什么是错的:( – 2011-04-11 12:48:40

+0

错误是在recvfrom函数中产生的 – 2011-04-11 12:49:27

回答

0

试试这个:(我将不得不在fork和fd的其他地方阅读)在fork的else中删除close,否则套接字会关闭,以致其他进程想要发回数据。

心连心

马里奥

+0

谢谢!!!!现在看来它的工作原理!!!! – 2011-04-11 13:29:37

+0

谢谢!虽然小心,但我不确定(并没有发现一个快速回答goggeling)如果这真的是一个好主意。在fork的fd是dup()'ed,所以它也应该工作。 – 2011-04-11 13:42:40

0

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

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

相关问题