现在在一个项目中要用到一个简单聊天室,就是没有所谓的服务器,每个客户端都要监听,我是简单的做了demo了是用WSAAsyncSelect做的,是不是用WSAAsyncSelect
比较会容易出现一些异常或者错误之类,由于我对网络编程不熟悉,没有经验不知道怎么捕捉和处理,大家给点经常会出现的异常,错误以及怎么处理,要是这个结构不好处理,是不是用阻塞,多线程比较好
比较会容易出现一些异常或者错误之类,由于我对网络编程不熟悉,没有经验不知道怎么捕捉和处理,大家给点经常会出现的异常,错误以及怎么处理,要是这个结构不好处理,是不是用阻塞,多线程比较好
WSAAsyncSelect适合client
我现在也用不好WSAAsyncSelect
大家有没有比较成熟的例子,有处理这种错误的,拜托了
为了解决这个问题,一般有:select,WSAAsyncSelect等模型来解决
send我是想把发送的数据放入一个自己开辟的buffer中,当数据发送成功时把buffer清空。要是,再次发送数据前判断是否buffer为空,为空就把新数据放入buffer,要是有WSAEWOULDBLOCK就等待FD_WRITE再次发送buffer中数据
这个思路大家看一下有没有错误,或者那里还需要补充的
如果你发的数据大,最好用如下结构:
do
{
int Ret=send(....);
}while(Ret==0);
do
{
int Ret=recv(..)
}while(Ret==0);
int nLeft=strlen(buffer);
int nRet;
while(nLeft)
{
nRet=send(...);
nLeft -=nRet;
}
int sendfun(SOCKET s,char * a,int len)
{
int ret = 0;
int idx =0;
while (len > 0)
{
ret = send(s,a+idx,len,0);
if ( ret == SOCKET_ERROR)
{
if ( WSAGetLastError() == 10035 )
{
break;//等待触发FD_WRITE,自动send发送位置从sendbuff+idx开始
}
else
{
return idx;//自己再次send,发送位置从sendbuff+idx开始, sendfun(socket,sendbuf+idx,len);
}
}
len -= ret;
idx += ret;
}
return 0;
}
{//判断出错原因
ierr = WSAGetLastError();
switch ( ierr )
{
case 10035:
{
while(bflag)
{
if ( connect(m_socket,(sockaddr*)(&m_connaddr),sizeof(m_connaddr)) == SOCKET_ERROR )
{
if( WSAGetLastError() != 10035 )
{
bflag = false;
}
}
else
{
bflag = false;
}
}
}
break;
default:
{
s.Format ("connect-errorcode-%d",WSAGetLastError());
m_msglist.InsertString (0,s);
closesocket(m_socket);
m_socket = INVALID_SOCKET;
}
break;
}
}
是不是用这个来检测WSAGETSELECTERROR(lParam)
是的,我们最好在确实事件的前面加上WSAGETSELECTERROR宏来判断套接字上是否发生了错误
3.recv一般不会出现10035错误,直接响应FD_READ来接收就好了,connect出现的的几率也很小,你这样的处理方式是可行的。
关键还是要把send的这个错误处理好,我大概看了一下,你的处理方式不错,基本上就是这样,就是响应FD_WRITE消息得到socket重新可写的通知,然后发送剩余的数据
{
closesocket((SOCKET)wParam);
break;
}
int TimeOut=6000; //设置发送超时6秒
if(::setsockopt(cClient,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){
return 0;
}
TimeOut=6000;//设置接收超时6秒
if(::setsockopt(cClient,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){
return 0;
}