关于在同一台机子上运行聊天室的服务器和客户端程序(急求!!)

Artist_jim 2012-04-16 12:41:22
我用C和SOCKET写了一个简单的多人聊天室(参考了网上别人的源代码),然后我在同一台机子上先运行服务器程序,然后运行客户端程序,结果发现客户端发送的信息没有发送的服务器上,也就导致服务器接受到的信息无法转发给各个客户端,求高手解释,现在上源码(我在2个源程序里面都附加了写没意思的语句printf主要是用来确定客户端的信息有没有发送到服务器)

/* 服务器 */
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/wait.h>

//person number who is chating
#define CHATNUM 8
int sd[CHATNUM];

// server send message that one client send to every client that online
void sendMsgToClient(int clientSocket)
{
char name[30];
char buffer[2048];
char temp[3000];

int i=0;
int returnValue=-1;
//get client's name
if((returnValue=recv(clientSocket,name,20,0))==-1)
{
perror("recv");
exit(1);
}
name[returnValue]=':';
name[returnValue]='\0';
printf("%s\n",name);
while(1)
{
//get the imformation that client send
returnValue=recv(clientSocket,buffer,1024,0);
if(returnValue==-1)
{
perror("recv");
exit(1);
}
//the client was offline

else if( returnValue==0)
{
printf("%sbye",name);
break;
}
/*
* find a socket that attact to client onlin
* send message to client online
*/
for(i=0;i<CHATNUM;i++)
{
if(sd[i]!=-1)
{
temp[0]='\0';
strcat(temp,name);
strcat(temp,buffer);
printf("%s\n",temp);
if(send(sd[i],temp,strlen(temp),0)==-1)
{
perror("send");
exit(1);
}
}
}
}
close(clientSocket);
for(i=0;i<CHATNUM;i++)
{
if(sd[i]==clientSocket)
{
sd[i]=-1;
}
}
pthread_exit(NULL);
}

int main()
{
int i=0;
int localSocket=0;

int clientSocket=0;
pthread_t pd;
struct sockaddr_in server_ip;
struct sockaddr_in client_ip;
socklen_t client_addr_size=0;
//init socket
memset(sd,-1,sizeof(sd));
if((localSocket=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("socket");
exit(1);
}
//set IP imformation
server_ip.sin_family=AF_INET;
server_ip.sin_port=htons(12345);
server_ip.sin_addr.s_addr=INADDR_ANY;
//bzero(&(server_ip.sin_zero),8);
if(bind(localSocket,(struct sockaddr *) &server_ip,\
sizeof(struct sockaddr ))==-1)
{
perror("bind");
exit(1);
}
if(listen(localSocket,10)==-1)
{
perror("listen");
exit(1);
}
while(1)
{
client_addr_size=sizeof(struct sockaddr_in);
if((clientSocket=accept(localSocket,(struct sockaddr *) &client_ip,\
&client_addr_size))==-1)
{
perror("accept");
exit(1);
}
//find a free socket
while(sd[i]==-1)
{
i=(i+1)%CHATNUM;
continue;
}
sd[i]=clientSocket;
pthread_create(&pd,NULL,(void *) sendMsgToClient,(int *)clientSocket);
}
return 0;
}



/*客户端*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <pthread.h>

void dellMsgFromServer(int sd)
{
char recvMsg[2000];
int recvMsgLen=0;
while(1)
{
if((recvMsgLen=recv(sd,recvMsg,1024,0))<0)
{
perror("recv");
exit(1);
}
recvMsg[recvMsgLen]='\0';
printf("%s\n",recvMsg);
}
pthread_exit(NULL);
}

int main()
{
char input[2000];
char clientName[20];
int sd;
pthread_t pd;
// set the server address
struct sockaddr_in client_addr;
client_addr.sin_family=AF_INET;
client_addr.sin_port=htons(12345);
if(inet_aton("127.0.0.1",&client_addr.sin_addr)==0)
{
perror("inet_aton");
exit(1);
}
bzero(&(client_addr.sin_zero),8);
if((sd=socket(AF_INET,SOCK_STREAM,0))<0)
{
perror("socket");
exit(1);
}
if(connect(sd,(struct sockaddr *)&client_addr,\
sizeof(struct sockaddr_in))!=0)
{
perror("connect");
exit(1);
}
printf("please input your name,note:your name lenth not over 20 byte\n");
scanf("%s",clientName);
if(send(sd,clientName,strlen(clientName),0)<0)
{
perror("send");
exit(1);
}

if(pthread_create(&pd,NULL,(void *)dellMsgFromServer,sd)!=0)
{
perror("pthread_create");
exit(1);
}
printf("pthread_create is success");
while(1)
{
scanf("%s",input);
if(send(sd,input,strlen(input),0)<0)
{
perror("send");
exit(1);
}
sleep(1);
}
close(sd);
return 0;
}
...全文
248 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Artist_jim 2012-04-16
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

能告诉我你急着要这个聊天室是作什么吗?
我刚好有个写好的在linux平台上运行的聊天室,不过是采用系统调用fork创建子进程(你的是采用线程),服务器端采用共享内存段的方式然后映射到进程虚拟地址空间的首地址以达到进程间进行数据的传输。
如果需要的话,我再把代码发给你。
[/Quote]
谢谢你,如果不介意的话给我吧,但是这个帖子是要解决我那个程序的问题,前面2个人帮我解决了问题,我把分数给他们,不能给你了。
Artist_jim 2012-04-16
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

你在哪里找的源码啊,你这个程序可以编译通过吗?
一眼看上去就很多毛病,你先把这几个地方改改:
1.线程调用
这个能通过编译吗?参数格式就不对吧?
C/C++ code
pthread_create(&pd,NULL,(void *) sendMsgToClient,(int *)clientSocket);


应该是
C/C++ code

void* sendMsgT……
[/Quote]
我那样写编译器只提醒,还是能通过编译的(我用的是GCC),我照你改了之后发现如果把线程执行的那个函数的参数定义成无类型的指针会发现后面无法强制类型转换成整形,如果没办法转换成整形,会导致SOCKET的表示出错,无法发送。
还有后面的那个client_addr 开始的时候的确是理解错了那个CONNECT的参数的含义,后面理解了之后变量名没改过来,但还是服务器的地址,这个没错(谢谢指出来,不然我可能不会发现)。也很感谢你。
Artist_jim 2012-04-16
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

服务器程序中的下面部分出现死循环,在第一个客户端进入的时候,在此处一直循环,始终不能调用下面的sd[i]=clientSocket;所以你的客户端数组永远都是-1.其实数据已经发送到了服务器。

//find a free socket
while(sd[i]==-1)
{
i=(i+1)%CHATNUM;
……
[/Quote]
太感谢了,这里写代码的时候不小心写错了应该是不等于-1的时候执行while语句
GDB我也用了,但是断点要一个个设置我只设置了觉得可能会出错的地方,以为那里不会错所以没设断点。
harveymorning 2012-04-16
  • 打赏
  • 举报
回复
能告诉我你急着要这个聊天室是作什么吗?
我刚好有个写好的在linux平台上运行的聊天室,不过是采用系统调用fork创建子进程(你的是采用线程),服务器端采用共享内存段的方式然后映射到进程虚拟地址空间的首地址以达到进程间进行数据的传输。
如果需要的话,我再把代码发给你。
ecsape 2012-04-16
  • 打赏
  • 举报
回复
你在哪里找的源码啊,你这个程序可以编译通过吗?
一眼看上去就很多毛病,你先把这几个地方改改:
1.线程调用
这个能通过编译吗?参数格式就不对吧?
pthread_create(&pd,NULL,(void *) sendMsgToClient,(int *)clientSocket);

应该是

void* sendMsgToClient(void *args)
pthread_create(&pd,NULL,sendMsgToClient,&clientSocket);

客户端的线程也一样
2.客户端里if(connect(sd,(struct sockaddr *)&client_addr,\
sizeof(struct sockaddr_in))!=0)
你好像没搞清楚connect的参数的含义,导致你对client_addr的设置错误及这个函数的错误
client_addr是你用来连接服务器的套接字地址,而你还需要一个要连接的服务器的套接字地址serv_addr
这个serv_addr才需要inet_aton,和设置端口为服务器的监听端口12345
你再看看别人的程序,把这部分改改


最后,你的收发的流程我没看太明白,建议你先简单的:客户端连接,发送字符,服务器收到字符,回复。这个流程你调试通了,再加上线程转发啥的。
A-post80 2012-04-16
  • 打赏
  • 举报
回复
服务器程序中的下面部分出现死循环,在第一个客户端进入的时候,在此处一直循环,始终不能调用下面的sd[i]=clientSocket;所以你的客户端数组永远都是-1.其实数据已经发送到了服务器。

//find a free socket
while(sd[i]==-1)
{
i=(i+1)%CHATNUM;
continue;
}

你的代码功能没太细看,至少注释了上面的while,服务器端有反应了,能打印出客户端发送的名字和输信息。
学学GDB,调试起来,很容易定位问题的。
Artist_jim 2012-04-16
  • 打赏
  • 举报
回复
求大侠们帮帮忙啊,自己顶下

23,121

社区成员

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

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