Linux下C插座:"坏的文件描述符"发生在接受()调用 [英] Linux C Socket:"bad file descriptor" occurs when accept() invokes

查看:412
本文介绍了Linux下C插座:"坏的文件描述符"发生在接受()调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写一个发送/使用Linux /插座/ TCP接收项目,我创建了一些线程发送或收到的消息,并使用一个全球性的队列来存储信息
code:

I am writing a send/receive project using linux/socket/tcp, I create some threads to send or recieve message,and use a global queue to store message Code:

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,accecpt()效果很好
但我发送消息test111111,坏文件描述符时接受()调用发生;
我发现,当排队()调用first_socket的变化,但我不能找到一个解决方案..anyone可以帮助我,THX

I send message "test" to the appliaction , accecpt() works well but I send message "test111111" ,"bad file descriptor" occurs when accept() invokes; and I find the 'first_socket' changes when EnQueue() invokes,but i cant find a solution ..anyone can help me ,THX

推荐答案

看起来你有内存溢出。 4个字节的测试数据不超支这么多,但10倍率足以引起麻烦。

Looks like you have a memory overrun. 4 bytes of test data don't overrun so much, but 10 override enough to cause trouble.

最有可能的受害者是 first_socket 变量。如果它的覆盖,那么第二个接受将得到错误的数量。结果
尝试打印 first_socket 之前每​​个接受通话,看我是对的。

The most likely victim is the first_socket variable. If it's overwritten, then the second accept will get the wrong number.
Try to print first_socket just before each accept call, to see if I'm right.

编辑:mark40意见,排队函数溢出其 A 变量

As mark40 comments, the EnQueue function overruns its a variable.

这篇关于Linux下C插座:"坏的文件描述符"发生在接受()调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆