Linux C套接字:当accept()调用时,会出现“错误的文件描述符”

时间:2012-07-10 15:11:05

标签: c linux sockets

我正在使用linux / socket / tcp编写一个发送/接收项目,我创建一些线程来发送或接收消息,并使用全局队列来存储消息 代码:

void EnQueue (M_queue queue,char * message,char * target_IP,char * target_IP_BAK)
{
    char a;
    char  * m=&a;
    strcpy(m,target_IP);
    M_element node=(M_element)malloc(sizeof(struct MessageNode ));
    node->message=message;
    node->target_IP=target_IP;
    node->next=NULL;
    if(IsQueueEmpty(queue))
    {
     queue->rear=queue->front=node;
    }
    else
    {
        queue->rear->next=node;
        queue->rear=node;
    }
}
M_queue messages;
void* receive_message();
void* send_message(void* args);
int main()
{



    pthread_t in_thread,out_thread;

    messages=(M_queue)malloc(sizeof(struct MessageQueue));
    init(messages);
    int ret=pthread_create(&in_thread,NULL,receive_message,NULL);
    if(ret==-1)

    {
        perror("thread receive:");
    }

    while(1)
    {
        if(!IsQueueEmpty(messages))
        {

            M_element message=DeQueue(messages);

            pthread_create(&out_thread,NULL,send_message,(void*)message);

        }


    }
    pthread_join(in_thread,NULL);
    return 0;


}
void*  send_message(void * args)
{
  struct sockaddr_in  sockaddr_out;
  M_element message=(M_element)args;
  int cfd=socket(AF_INET,SOCK_STREAM,0);
  if(cfd==-1)
  {
      perror("send_socket");

      exit(1);
  }
  sockaddr_out.sin_family=AF_INET;
  sockaddr_out.sin_port=htons(9734);
  printf("%s\n",message->target_IP);
  sockaddr_out.sin_addr.s_addr=inet_addr(message->target_IP);
  int ret=connect(cfd,(struct sockaddr *)&sockaddr_out,sizeof(sockaddr_out));
  if(ret==-1)
  {
      perror("connect");
      offline_message(message->target_IP,message->message); 
      exit(1);
  }
  if(write(cfd,message->message,strlen(message->message)+1)==-1)
  {
      perror("write");
      exit(1);
  }
  close(cfd);
}
void*  receive_message()
{
    char  buf[256];
    char IP[256];
    memset(IP,0,256);
    int first_socket=socket(AF_INET,SOCK_STREAM,0);
    if(first_socket==-1)
    {
        perror("socket");
        exit(1);
    }
    struct sockaddr_in in_socketaddr;
    in_socketaddr.sin_family=AF_INET;
    in_socketaddr.sin_port=htons(9999);
    in_socketaddr.sin_addr.s_addr=INADDR_ANY;
    int ret=bind(first_socket,(struct  sockaddr *)&in_socketaddr,sizeof(in_socketaddr));
    if (ret==-1)
    {
        perror("bind");
        exit(1);
    }
    ret=listen(first_socket,10);
    if(ret==-1)
    {
        perror("listen");
        exit(1);
    }

    int accept_socket;


    while(1)
    {
        **//error occurs**
        **accept_socket=accept(first_socket,NULL,NULL);**
        printf("%d!",first_socket);
        if(accept_socket==-1)
        {
            perror("accept");
            exit(1);
        }
        int ret=read(accept_socket,buf,sizeof(buf));
        close(accept_socket);
        if(ret==-1)
        {
            perror("read1");
            exit(1);
        }

        findIP(buf,IP);
        **EnQueue(messages,buf,IP,IP);**
        printf("%d!",first_socket);


    }
    close(first_socket);
}

我向appliaction发送消息“test”,accecpt()效果很好 但是当发出accept()调用时,我发送消息“test111111”,“坏文件描述符”; 当EnQueue()调用时,我发现'first_socket'发生了变化,但是我无法找到解决方案..任何人都可以帮助我,THX

1 个答案:

答案 0 :(得分:4)

看起来你的内存超支了。 4个字节的测试数据不会超出这么多,但10个覆盖足以引起麻烦。

最可能的受害者是first_socket变量。如果它被覆盖,那么第二个accept将得到错误的数字 尝试在每次first_socket来电之前打印accept,看看我是否正确。

编辑:作为mark40条评论,EnQueue函数超出其a变量。