首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > UNIXLINUX >

写了一个linux下即使聊天程序,聊天部分出现一个有关问题

2013-08-09 
写了一个linux下即使聊天程序,聊天部分出现一个问题刚学linux编程不久,就急着上手写点东西,现在写到对话部

写了一个linux下即使聊天程序,聊天部分出现一个问题
刚学linux编程不久,就急着上手写点东西,现在写到对话部分,群聊是没问题,就私聊遇到问题,这里将输入的首字母作为区分,‘#’为群聊,‘$’为私聊,以下是服务端和客户端部分代码,
 int  speakall(LinkList L,char buf[],int size)//群聊函数。链表节点为存储用户的信息结构体
 {
    
     LinkList p;
     int socket;
     if(!L)
         return -1;
     p=L->next;
     while(p!=NULL)
     {
       if(p->user.state==1)
        {
            socket=p->user.mysockfd;
            sendto_client(&socket,buf,size);
        }
         p=p->next;
     }
 }
 int chat_server(int *socket,char name[])
 {
    int i;
    int len;
    int running=1,recvsize;
    
    char filepath[60];
    int filesocket;
    
    struct tm *pt;
    time_t t;
    char option;
    char buf1[MAX_RECVSIZE];
    char buf2[MAX_TEXTSIZE];
    char id[10];
    int destsocket;
 
   memset(buf2,0,MAX_TEXTSIZE);
    sprintf(buf2,"%s 上线 !\n",name);
    speakall(L,buf2,strlen(buf2));
 
   while(1)
       {
             memset(id,0,10);
             memset(buf1,0,MAX_RECVSIZE);
             memset(buf2,0,MAX_TEXTSIZE);
             memset(filepath,0,60);
 
            if((recvsize=recv(*socket,buf1,MAX_RECVSIZE,0))<=0)
                {
                    perror("recv";
                    printf("用户 %s 掉线 \n",name);


                    pthread_exit(NULL);
                }
               
              option=buf1[0];
                
              switch(option)
                 {
                     case '#'://群聊
                          {
                             time(&t);
                             pt=localtime(&t);
                            
                             sprintf(buf2,"%s 对大家说%02d:%02d:%02d)\n %s",name,pt->tm_hour,pt->tm_min,pt->tm_sec,buf1);
                             speakall(L,buf2,strlen(buf2));
                             break;                         
                         }
                      case '$'://私聊
                          {
                              time(&t);


                              pt=localtime(&t);
                              
                              for(i=1;((buf1[i]!=' ') && (i<MAX_RECVSIZE));i++)
                                  id[i-1]=buf1[i];//提取要私聊人的名字
                               if((LocateName(L,id)<0) || i==1 || (i>MAX_RECVSIZE))
                                       break;
                               destsocket=LocateUsersocket(L,id);
                               sprintf(buf2,"%s 对你说 %02d:%02d:%02d\n%s\n)",name,pt->tm_hour,pt->tm_min,pt->tm_sec,buf1);
                               
                               sendto_client(&destsocket,buf2,strlen(buf2)+1);
                               break;
                          }
                      case '@' :
                          {
                             ..........................


                          }
                 }
       }
 
}
 客户端省略部分代码
 void pthread_chat()//此处开辟线程是为了收集来自服务器的信息,并发送给另个进程显示信息
{
    int len;
    int chat_fd;
    char buf[MAX_TEXT];
    char flag;
    running=1;
    int i;
    char socket[6];
    memset(socket,0,6);
    char filename[50];
    if((chat_fd=open(chatdata_path,O_APPEND |O_WRONLY,0666))<0)
      {
           perror("open");
      }
      my_message msg;
      msg.message_type=1;
      while(running)
      {
          memset(buf,0,MAX_TEXT);
          recvfrom_server(buf,MAX_TEXT);
          flag=buf[0];
          if(flag=='!')
            {
                .....无关聊天省略
            }
        strcpy(msg.buf,buf);
         if(msgsnd(msg_id,(void *)&msg,MAX_TEXT,0)==-1)
         {
                perror("msgsnd");
                exit(-1);
         } 
      } 
}
int chat_client()
{
    pthread_t pid;
    if(pthread_create(&pid,NULL,(void *)pthread_chat,NULL)<0)
       {
            perror("pthread_create");
            exit(-1);
       }


    int sendsize;
    char buf[50];
    char option;
    int i;
    running=1;
    recvfrom_server(buf,50);
    printf("%s\n",buf);
    while(running)
         {
              memset(buf,0,50);
              fgets(buf,50,stdin);
              printf("buf=%s\n",buf);
              if(confirm==1)
                {
                   option=buf[0];
                   switch(option)
                    {
                         .......
                    }
                }
              if(buf[0]=='@')
               {
                   .........
               }
               sendsize=strlen(buf);
               if(sendsize)
               {
                    printf("1\n");
                  if(send(socketSrv,buf,sendsize,0)==-1)
                    {
                           perror("send");


                           exit(-1);
                    }
                  printf("2\n");
               } 
         }
          return 0;
}这里的信息显示我是通过进程间通讯发送到另外个程序显示,也就死是2个终端为一个客户,现在的问题是登录2个用户之后,第一个登录的能发起私聊,第二个登录可以群聊,但是一发送私聊就出错,很是纳闷,也没调出个结果,报的是这个错误 send: Bad file descriptor,是发送有什么问题吗,以上就涉及客户端和服务端2个发送,那为什么第一个可以,第二个就不行,和线程设计有关吗(用户登录部分设计了一个线程,让多用户登录)?
[解决办法]
gdb调试当然可以,不过调试多线程稍麻烦,建议你把客户端多线程先去掉,从逻辑上意义不是特别大的。

热点排行