下面是用到的其中一个函数
现在是运行的过程中,一旦accept()出现问题的话,程序就阻塞了。
也不知道应该如何去设置超时时间,先前设定的也没有用。
于是请教诸位了。也查过一些网页,想问问看看能不能不用 非阻塞socket的程序,就能解决这个问题。
//Upload用来向服务器上载一个文件,调用前需要设置属性m_IdeaID,m_TaskID
//这时客户机是Socket Server,服务器是Socket Client
BOOL CSystemStatus::Upload(CString strFilename)
{
//先判断能否打开文件
CFile myFile;
if(!myFile.Open(strFilename, CFile::modeRead | CFile::typeBinary))
{
AfxMessageBox("无法打开文件:"+strFilename);
return FALSE;
} //服务器IP地址
CString strServerIP = GetServerIP();
//客户端IP地址
CString strClientIP = GetClientIP(); //向服务器登记需要上载的文件信息
TransferFile upInfo;
upInfo.IdeaID = m_IdeaID;
upInfo.TaskID = m_TaskID;
upInfo.Directory = m_Directory;
upInfo.Sender = "Client"; //客户机发送
upInfo.SendIP = strClientIP;
upInfo.Receiver = "Server"; //服务器接收
upInfo.RecIP = strServerIP;
upInfo.FileName = GetFileName(strFilename); //上载的文件名,这个文件名含有路径,这里需要把路径去掉
upInfo.Flag = "0"; //设置未处理标志,等待服务器处理
CTransferFilesDB transfer;
transfer.ExecuteInsert(upInfo); //存入数据库 AfxSocketInit(NULL);
CSocket sockSrvr;
sockSrvr.Create(PORT); // Creates our server socket
sockSrvr.Listen(); // Start listening for the client at PORT int TimeOut=6000; //设置发送超时6秒
if(::setsockopt(sockSrvr,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
return 0;
}
TimeOut=6000;//设置接收超时6秒
if(::setsockopt(sockSrvr,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){
return 0;
}
CSocket sockRecv;
sockSrvr.Accept(sockRecv); // Use another CSocket to accept the connection
TimeOut=6000; //设置发送超时6秒
if(::setsockopt(sockRecv,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
return 0;
}
TimeOut=6000;//设置接收超时6秒
if(::setsockopt(sockRecv,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){
return 0;
} if(sockRecv==INVALID_SOCKET)
{
//错误处理
AfxMessageBox("超时错误!");
return FALSE;
}
AfxMessageBox("接收连接成功");
int myFileLength = myFile.GetLength(); // Going to send the correct File Size sockRecv.Send(&myFileLength, 4); // 4 bytes long
char sendBuf[MM];
for(int i=0;i<=myFileLength;i+=MM)
{
myFile.Read(sendBuf, sizeof(sendBuf));
sockRecv.Send(sendBuf,sizeof(sendBuf)); //Send the whole thing now
Sleep(10);
}
if(myFileLength%MM!=0)
{
myFile.Read(sendBuf, myFileLength%MM);
sockRecv.Send(sendBuf,myFileLength%MM);
Sleep(10);
}
myFile.Close(); sockRecv.Close();
return TRUE;
}
现在是运行的过程中,一旦accept()出现问题的话,程序就阻塞了。
也不知道应该如何去设置超时时间,先前设定的也没有用。
于是请教诸位了。也查过一些网页,想问问看看能不能不用 非阻塞socket的程序,就能解决这个问题。
//Upload用来向服务器上载一个文件,调用前需要设置属性m_IdeaID,m_TaskID
//这时客户机是Socket Server,服务器是Socket Client
BOOL CSystemStatus::Upload(CString strFilename)
{
//先判断能否打开文件
CFile myFile;
if(!myFile.Open(strFilename, CFile::modeRead | CFile::typeBinary))
{
AfxMessageBox("无法打开文件:"+strFilename);
return FALSE;
} //服务器IP地址
CString strServerIP = GetServerIP();
//客户端IP地址
CString strClientIP = GetClientIP(); //向服务器登记需要上载的文件信息
TransferFile upInfo;
upInfo.IdeaID = m_IdeaID;
upInfo.TaskID = m_TaskID;
upInfo.Directory = m_Directory;
upInfo.Sender = "Client"; //客户机发送
upInfo.SendIP = strClientIP;
upInfo.Receiver = "Server"; //服务器接收
upInfo.RecIP = strServerIP;
upInfo.FileName = GetFileName(strFilename); //上载的文件名,这个文件名含有路径,这里需要把路径去掉
upInfo.Flag = "0"; //设置未处理标志,等待服务器处理
CTransferFilesDB transfer;
transfer.ExecuteInsert(upInfo); //存入数据库 AfxSocketInit(NULL);
CSocket sockSrvr;
sockSrvr.Create(PORT); // Creates our server socket
sockSrvr.Listen(); // Start listening for the client at PORT int TimeOut=6000; //设置发送超时6秒
if(::setsockopt(sockSrvr,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
return 0;
}
TimeOut=6000;//设置接收超时6秒
if(::setsockopt(sockSrvr,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){
return 0;
}
CSocket sockRecv;
sockSrvr.Accept(sockRecv); // Use another CSocket to accept the connection
TimeOut=6000; //设置发送超时6秒
if(::setsockopt(sockRecv,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
return 0;
}
TimeOut=6000;//设置接收超时6秒
if(::setsockopt(sockRecv,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR){
return 0;
} if(sockRecv==INVALID_SOCKET)
{
//错误处理
AfxMessageBox("超时错误!");
return FALSE;
}
AfxMessageBox("接收连接成功");
int myFileLength = myFile.GetLength(); // Going to send the correct File Size sockRecv.Send(&myFileLength, 4); // 4 bytes long
char sendBuf[MM];
for(int i=0;i<=myFileLength;i+=MM)
{
myFile.Read(sendBuf, sizeof(sendBuf));
sockRecv.Send(sendBuf,sizeof(sendBuf)); //Send the whole thing now
Sleep(10);
}
if(myFileLength%MM!=0)
{
myFile.Read(sendBuf, myFileLength%MM);
sockRecv.Send(sendBuf,myFileLength%MM);
Sleep(10);
}
myFile.Close(); sockRecv.Close();
return TRUE;
}
选择套接字
异步选择套接字
事件选择套接字
重叠套接字
我试验了一下
CAsyncSocket m_SocketServer;
Csocket m_pSocket;
int TimeOut=6000;
oldtime = GetTickCount();
while (GetTickCount() - oldtime < TimeOut)
{
bAccept = m_SocketServer.Accept(*m_pSocket);
if (bAccept)
{
/////成功处理
break; }
else
{
continue;
}
}
是一个非阻塞就可以
大人能不能更详细一些。
是说用多线程么?
这个“不能阻塞在accept上面”是什么意思?
哦,我看快了点,误解你的意思了。现在是运行的过程中,一旦accept()出现问题的话,程序就阻塞了。
也不知道应该如何去设置超时时间,先前设定的也没有用。
于是请教诸位了。 accept出现什么问题,导致你如此阻塞?描述一下。
m_hAcceptEvent = WSACreateEvent();
if(m_hAcceptEvent == NULL)
{
DeInitServer();
return FALSE;
}
//将监听的SOCKET设置EVENSELCT模型
nCode = WSAEventSelect(m_ServSock, m_hAcceptEvent, FD_ACCEPT);
if(nCode == SOCKET_ERROR)
{
DeInitServer();
return FALSE;
}接受连接的线程 DWORD WINAPI AcceptThread(LPVOID lParam)
{
SOCKET ListenSocket = (SOCKET)lParam;//这个参数是你的监听SOCKET
WSANETWORKEVENTS WSAEvents;
while(WAIT_OBJECT_0 != WaitForSingleObject(g_hShutdownEvent, 0))
{
if (WSA_WAIT_TIMEOUT != WSAWaitForMultipleEvents(1, &g_hAcceptEvent, FALSE, 0, FALSE))
{
WSAEnumNetworkEvents(ListenSocket, g_hAcceptEvent, &WSAEvents);
if ((WSAEvents.lNetworkEvents & FD_ACCEPT) && (0 == WSAEvents.iErrorCode[FD_ACCEPT_BIT]))
{
//处理并接受就是了
AcceptConnection();
}
}
}
return 0;
}