因为你使用的只是read的参数,还有一个write 的参数,不过一般上对于发送数据是不需要的,MSDN上介绍: readfds:If listen has been called and a connection is pending, accept will succeed. Data is available for reading (includes OOB data if SO_OOBINLINE is enabled). Connection has been closed/reset/terminated. writefds:If processing a connect call (nonblocking), connection has succeeded. Data can be sent. exceptfds:If processing a connect call (nonblocking), connection attempt failed. OOB data is available for reading (only if SO_OOBINLINE is disabled).
本帖最后由 VisualEleven 于 2011-05-16 22:12:36 编辑
客户端:在控制台上创建界面,画了三个窗口。即主窗口(显示聊天内容),用户列表窗口(就是显示在聊天室的用户名),最后是输内容的窗口。 服务端:就是一个黑框框。协议时tcp/ip 我设想的思路是:服务器打开,等待客户端的连接;客户端运行:(因为在黑框框运行)输入可执行文件,即<.exe文件> <IP> <用户名> ,(用户名在server都记入在一个数组里)连接成功,client就进入界面。server端发送所有登陆的用户名给新登入client,并且给老用户发送新登入用户名(这里就觉得有问题,问题在后面说明),然后就可以相互两天,client将输入内容发给server,server收到后发给所有用户,用户接受了显示在主窗口上。思路就这样子。 现在的问题就是这样:第一个client登入以后,一切都正常,就是预期那样,用户列表也有了,也可以输入内容。但是如果client1没有输内容,就是不聊天,此时第二个用户登入了,也成功进入界面,但是此时用户列表上一个用户名也没有,也不能输入内容,就是无法响应键盘输入,(比如键盘按了abc,但在输入窗口是没有显示内容的)(但是键盘的内容应该是被保存下来了,为什么呢?下面会提到),而client1就可以输入内容,但是client1输完内容,按回车键,预期是发送过去,应该显示到主窗口上去,可是按完回车键不会有反应了,内容还是在输入窗口上。此时,client2就激活了一样,用户列表上显示了所有用户名,而且也能发送内容,他自身的窗口会有他的内容,而client1窗口接受不到,就好比阻塞了一样,一点反应都没有。(总觉得在client收发端没有处理好,因为新客户什么时候登入没有个准,难道每个client来用一个线程专门来收发?(我现在的想法))if(!(StartLinkServer(argc,argv[1],argv[2],&sClient)))//这个就是实现登入服务器,成功就有socket,就 { //是一般的创建,绑定,监听 cout<<"Becouse of Internet problem,you can not be into the ChatRoom,sorry!"<<endl; return; } IntoChat_Windows();//进入界面函数 while(1) { My_Recv(&sClient,pChatMessage,BUFFER_MESSAGE_SIZE);//如果有新用户,server就发/new来做提示 if(strcmp(pChatMessage,"/new") == 0) Flag = true; if(Flag) { ReciveTheUsername(&sClient,pUsername);//就是接受用户名,添加到用户列表上去 Flag = false;//没有新用户就false } SetFocusConsoleWindow(&MessageWindow);//将光标置到输入窗口上 InputDataConsoleWindow(&MessageWindow,pChatMessage,BUFFER_MESSAGE_SIZE);//输入内容 My_Send(&sClient,pChatMessage,strlen(pChatMessage));//发送输入内容 if((Ret = My_Recv(&sClient,pChatMessage,BUFFER_MESSAGE_SIZE)) == SOCKET_ERROR)//接受内容 { errornum = WSAGetLastError(); cout<<"CLient recieve the meaning is failed! ERROR:"<<errornum<<endl; closesocket(sClient); WSACleanup(); return; }
为什么?
----------------------------------------
其它的client不能发送数据?是不是你的client的recv阻塞了没有返回还是怎么的?
readfds:If listen has been called and a connection is pending, accept will succeed.
Data is available for reading (includes OOB data if SO_OOBINLINE is enabled).
Connection has been closed/reset/terminated. writefds:If processing a connect call (nonblocking), connection has succeeded.
Data can be sent. exceptfds:If processing a connect call (nonblocking), connection attempt failed.
OOB data is available for reading (only if SO_OOBINLINE is disabled).
服务端:就是一个黑框框。协议时tcp/ip
我设想的思路是:服务器打开,等待客户端的连接;客户端运行:(因为在黑框框运行)输入可执行文件,即<.exe文件> <IP> <用户名> ,(用户名在server都记入在一个数组里)连接成功,client就进入界面。server端发送所有登陆的用户名给新登入client,并且给老用户发送新登入用户名(这里就觉得有问题,问题在后面说明),然后就可以相互两天,client将输入内容发给server,server收到后发给所有用户,用户接受了显示在主窗口上。思路就这样子。
现在的问题就是这样:第一个client登入以后,一切都正常,就是预期那样,用户列表也有了,也可以输入内容。但是如果client1没有输内容,就是不聊天,此时第二个用户登入了,也成功进入界面,但是此时用户列表上一个用户名也没有,也不能输入内容,就是无法响应键盘输入,(比如键盘按了abc,但在输入窗口是没有显示内容的)(但是键盘的内容应该是被保存下来了,为什么呢?下面会提到),而client1就可以输入内容,但是client1输完内容,按回车键,预期是发送过去,应该显示到主窗口上去,可是按完回车键不会有反应了,内容还是在输入窗口上。此时,client2就激活了一样,用户列表上显示了所有用户名,而且也能发送内容,他自身的窗口会有他的内容,而client1窗口接受不到,就好比阻塞了一样,一点反应都没有。(总觉得在client收发端没有处理好,因为新客户什么时候登入没有个准,难道每个client来用一个线程专门来收发?(我现在的想法))if(!(StartLinkServer(argc,argv[1],argv[2],&sClient)))//这个就是实现登入服务器,成功就有socket,就
{ //是一般的创建,绑定,监听
cout<<"Becouse of Internet problem,you can not be into the ChatRoom,sorry!"<<endl;
return;
}
IntoChat_Windows();//进入界面函数
while(1)
{
My_Recv(&sClient,pChatMessage,BUFFER_MESSAGE_SIZE);//如果有新用户,server就发/new来做提示
if(strcmp(pChatMessage,"/new") == 0)
Flag = true;
if(Flag)
{
ReciveTheUsername(&sClient,pUsername);//就是接受用户名,添加到用户列表上去
Flag = false;//没有新用户就false
} SetFocusConsoleWindow(&MessageWindow);//将光标置到输入窗口上
InputDataConsoleWindow(&MessageWindow,pChatMessage,BUFFER_MESSAGE_SIZE);//输入内容 My_Send(&sClient,pChatMessage,strlen(pChatMessage));//发送输入内容
if((Ret = My_Recv(&sClient,pChatMessage,BUFFER_MESSAGE_SIZE)) == SOCKET_ERROR)//接受内容
{
errornum = WSAGetLastError();
cout<<"CLient recieve the meaning is failed! ERROR:"<<errornum<<endl;
closesocket(sClient);
WSACleanup();
return;
}
ClearConsoleWindow(&MessageWindow);//清空输入窗口内容
InputChatMessage(&MainWindow,pChatMessage);//显示到主窗口上
}就是这样