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

闲人1991 2013-08-02 09:23:46
刚学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个发送,那为什么第一个可以,第二个就不行,和线程设计有关吗(用户登录部分设计了一个线程,让多用户登录)?
...全文
101 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
gdb调试当然可以,不过调试多线程稍麻烦,建议你把客户端多线程先去掉,从逻辑上意义不是特别大的。
闲人1991 2013-08-05
  • 打赏
  • 举报
回复
引用 1 楼 songsong33 的回复:
代码太长,没看。从原因判断就是socket句柄不对,应该是赋值保存的是否错误了,可以在socket保存的时候和发送的时候打印socket句柄地址看看是否一致。
根据你说的,打印了一下是socket有问题,刚开始2个打印出来,等进入私聊函数的时候,打印显示第二个的被第一占用了,第二个的socket号显示的-1,可是我这个查找socket是从链表结构存储的信息中查询的,而它的更新是在登录的时候,我也在这个地方打印出来,都是正确的socket存入的,怎么会出现这种情况?GDB可以调试这样的2个进程吗?不调试找不出原因呀。
  • 打赏
  • 举报
回复
代码太长,没看。从原因判断就是socket句柄不对,应该是赋值保存的是否错误了,可以在socket保存的时候和发送的时候打印socket句柄地址看看是否一致。

23,121

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧