客户端socket编程需要用线程吗 是不是socket都要用线程?我直接用函数,send()能成功,但recv()不行。如果是,能给我个代码例程吗? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 你用的是csokcet还是winsock然后用的是什么网络模型? 用的是winsock WSAAsyncSelect 模型 你要多接收几次,比如你发送20byte,你接收了10byte那还有10个要在接收! 你要多接收几次,比如你发送20byte,你接收了10byte那还有10个要在接收! 你要多接收几次,比如你发送20byte,你接收了10byte那还有10个要在接收! WSAAsyncSelect不需要用线程,接收消息即可 1. if (WSAAsyncSelect(m_hSocket, m_hMainWnd, nMsgID, lEvent) == SOCKET_ERROR) return FALSE;2. 指定消息映射函数3. 消息处理LPARAM OnClientSockMsg(WPARAM wParam, LPARAM lParam){ if (wParam == 0 && lParam == 0) return 0; if (WSAGETSELECTERROR(lParam)) { OnSocketClose(); m_status = STATUS_NONE; return 0; } switch (WSAGETSELECTEVENT(lParam)) { case FD_CONNECT: { if (!InitThread(SelectModelMsgThread, (LPVOID)this)) break; OnSocketConnect(); m_status = STATUS_CONNECT; } break; case FD_CLOSE: { OnSocketClose(); m_status = STATUS_NONE; } break; case FD_READ: { OnSocketRead(); m_status = STATUS_READ; } break; default: break; } return 1;} 我的代码:1、对话框初始化程序,socket主程序BOOL CsocketDlg::OnInitDialog(){ ..... // TODO: Add extra initialization here //---------------------- // Declare and initialize variables. WSADATA wsaData; int iResult; CString strMessageTemp; struct sockaddr_in clientService; char *sendbuf = "abc"; //---------------------- // Initialize Winsock iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != NO_ERROR) { strMessageTemp.Format(_T("WSAStartup error:%d"), iResult); AfxMessageBox(strMessageTemp); return FALSE; } //---------------------- // Create a SOCKET for connecting to server m_ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (m_ConnectSocket == INVALID_SOCKET) { strMessageTemp.Format(_T("socket error:%d"), WSAGetLastError()); AfxMessageBox(strMessageTemp); WSACleanup(); return FALSE; } //---------------------- // The sockaddr_in structure specifies the address family, // IP address, and port of the server to be connected to. clientService.sin_family = AF_INET; clientService.sin_addr.s_addr = inet_addr( "127.10.0.1" ); clientService.sin_port = htons( 5000); //---------------------- // Connect to server. iResult = connect( m_ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) ); if ( iResult == SOCKET_ERROR) { closesocket (m_ConnectSocket); strMessageTemp.Format(_T("connect error:%d"), WSAGetLastError()); AfxMessageBox(strMessageTemp); WSACleanup(); return FALSE; } //---------------------- //network events[WSAAsyncSelect model], if there is data to read or write, WM_SOCKET message will be activated iResult = WSAAsyncSelect(m_ConnectSocket, this->m_hWnd, WM_SOCKET, FD_READ|FD_WRITE|FD_CLOSE); if (iResult != 0) { strMessageTemp.Format(_T("WSAAsyncSelect failed: %d\n"), WSAGetLastError()); AfxMessageBox(strMessageTemp); closesocket(m_ConnectSocket); WSACleanup(); return FALSE; } // Send an initial buffer iResult = send( m_ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 ); if (iResult == SOCKET_ERROR) { strMessageTemp.Format(_T("send failed: %d\n"), WSAGetLastError()); AfxMessageBox(strMessageTemp); closesocket(m_ConnectSocket); WSACleanup(); return FALSE; } strMessageTemp.Format(_T("Bytes Sent: %d\n"), iResult); AfxMessageBox(strMessageTemp); // Disable the function of sending since no more data will be sent iResult = shutdown(m_ConnectSocket, SD_SEND); if (iResult == SOCKET_ERROR) { strMessageTemp.Format(_T("shutdown failed: %d\n"), WSAGetLastError()); AfxMessageBox(strMessageTemp); closesocket(m_ConnectSocket); WSACleanup(); return FALSE; } // cleanup closesocket(m_ConnectSocket); WSACleanup(); return TRUE; // return TRUE unless you set the focus to a control }2、消息函数LRESULT CsocketDlg::OnSocket(WPARAM wParam, LPARAM lParam){ int iResult; char recvbuf[DEFAULT_BUFLEN]; int recvbuflen = DEFAULT_BUFLEN; CString strMessageTemp; if (wParam == 0 && lParam == 0) return 0; if (WSAGETSELECTERROR(lParam)) { //OnSocketClose(); return 0; } switch (WSAGETSELECTEVENT(lParam)) { case FD_CONNECT: { //if (!InitThread(SelectModelMsgThread, (LPVOID)this)) //break; AfxMessageBox(_T("connecting..."));; } break; case FD_CLOSE: { AfxMessageBox(_T("close..."));; } break; case FD_WRITE: { AfxMessageBox(_T("send..."));; } break; case FD_READ: { AfxMessageBox(_T("read..."));; do { iResult = recv(m_ConnectSocket, recvbuf, recvbuflen, 0); if ( iResult > 0 ) { strMessageTemp.Format(_T("Bytes received: %d\n"), iResult); AfxMessageBox(strMessageTemp); } else if ( iResult == 0 ) AfxMessageBox(_T("Connection has been gracefully closed\n")); else { strMessageTemp.Format(_T("recv failed: %d\n"), WSAGetLastError()); AfxMessageBox(strMessageTemp); } } while( iResult > 0 ); } break; default: break; } // Receive until the peer closes the connection return 1;}结果:发送成功,接收部分不能触发。请教[happysheepherder],是什么问题? WSAAsyncSelect本来就是异步模式,靠消息驱动,不需要多线程。MFC可以重载pretranslate函数实现 ON_MESSAGE(WM_CLIENT_ACCEPT,OnAccept) ON_MESSAGE(WM_CLIENT_READCLOSE,OnReadClose)你有没有消息映射 BEGIN_MESSAGE_MAP(CsocketDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_MESSAGE(WM_SOCKET, OnSocket) //}}AFX_MSG_MAPEND_MESSAGE_MAP() socket问题 如何通过单击按钮来启动别的软件 第2次LoadBitmap(IDB_BITMAP)后出错,急!! 为什么在mfc的源代码里面找不到某些函数的实现? 在.NET下出现了C2664错误,怎么解决. 在线等中.... 谢谢 怎样打开SQLserver数据库 共享内存的问题,用VC共享内存后,保存一些数据,让JAVA程序能使用这些数据呢??? 有关CListView的增强类 .sit是个什末文件?用什末才能打开? 请巨虾指点!!! 求一ATL正则! callback函数
然后用的是什么网络模型?
WSAAsyncSelect 模型
return FALSE;2. 指定消息映射函数3. 消息处理LPARAM OnClientSockMsg(WPARAM wParam, LPARAM lParam)
{
if (wParam == 0 && lParam == 0)
return 0; if (WSAGETSELECTERROR(lParam))
{
OnSocketClose();
m_status = STATUS_NONE;
return 0;
} switch (WSAGETSELECTEVENT(lParam))
{
case FD_CONNECT:
{
if (!InitThread(SelectModelMsgThread, (LPVOID)this))
break;
OnSocketConnect();
m_status = STATUS_CONNECT;
}
break; case FD_CLOSE:
{
OnSocketClose();
m_status = STATUS_NONE;
}
break; case FD_READ:
{
OnSocketRead();
m_status = STATUS_READ;
}
break; default:
break;
}
return 1;
}
1、对话框初始化程序,socket主程序
BOOL CsocketDlg::OnInitDialog()
{
.....
// TODO: Add extra initialization here //----------------------
// Declare and initialize variables.
WSADATA wsaData;
int iResult;
CString strMessageTemp;
struct sockaddr_in clientService;
char *sendbuf = "abc";
//----------------------
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != NO_ERROR)
{
strMessageTemp.Format(_T("WSAStartup error:%d"), iResult);
AfxMessageBox(strMessageTemp);
return FALSE;
} //----------------------
// Create a SOCKET for connecting to server
m_ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (m_ConnectSocket == INVALID_SOCKET)
{
strMessageTemp.Format(_T("socket error:%d"), WSAGetLastError());
AfxMessageBox(strMessageTemp);
WSACleanup();
return FALSE;
} //----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port of the server to be connected to.
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr( "127.10.0.1" );
clientService.sin_port = htons( 5000); //----------------------
// Connect to server.
iResult = connect( m_ConnectSocket, (SOCKADDR*) &clientService, sizeof(clientService) );
if ( iResult == SOCKET_ERROR)
{
closesocket (m_ConnectSocket);
strMessageTemp.Format(_T("connect error:%d"), WSAGetLastError());
AfxMessageBox(strMessageTemp);
WSACleanup();
return FALSE;
} //----------------------
//network events[WSAAsyncSelect model], if there is data to read or write, WM_SOCKET message will be activated
iResult = WSAAsyncSelect(m_ConnectSocket, this->m_hWnd, WM_SOCKET, FD_READ|FD_WRITE|FD_CLOSE);
if (iResult != 0)
{
strMessageTemp.Format(_T("WSAAsyncSelect failed: %d\n"), WSAGetLastError());
AfxMessageBox(strMessageTemp);
closesocket(m_ConnectSocket);
WSACleanup();
return FALSE;
} // Send an initial buffer
iResult = send( m_ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 );
if (iResult == SOCKET_ERROR)
{
strMessageTemp.Format(_T("send failed: %d\n"), WSAGetLastError());
AfxMessageBox(strMessageTemp);
closesocket(m_ConnectSocket);
WSACleanup();
return FALSE;
} strMessageTemp.Format(_T("Bytes Sent: %d\n"), iResult);
AfxMessageBox(strMessageTemp); // Disable the function of sending since no more data will be sent
iResult = shutdown(m_ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR)
{
strMessageTemp.Format(_T("shutdown failed: %d\n"), WSAGetLastError());
AfxMessageBox(strMessageTemp);
closesocket(m_ConnectSocket);
WSACleanup();
return FALSE;
} // cleanup
closesocket(m_ConnectSocket);
WSACleanup();
return TRUE; // return TRUE unless you set the focus to a control
}2、消息函数
LRESULT CsocketDlg::OnSocket(WPARAM wParam, LPARAM lParam)
{
int iResult;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
CString strMessageTemp; if (wParam == 0 && lParam == 0)
return 0; if (WSAGETSELECTERROR(lParam))
{
//OnSocketClose();
return 0;
} switch (WSAGETSELECTEVENT(lParam))
{
case FD_CONNECT:
{
//if (!InitThread(SelectModelMsgThread, (LPVOID)this))
//break;
AfxMessageBox(_T("connecting..."));;
}
break; case FD_CLOSE:
{
AfxMessageBox(_T("close..."));;
}
break; case FD_WRITE:
{
AfxMessageBox(_T("send..."));;
}
break; case FD_READ:
{
AfxMessageBox(_T("read..."));;
do { iResult = recv(m_ConnectSocket, recvbuf, recvbuflen, 0);
if ( iResult > 0 )
{
strMessageTemp.Format(_T("Bytes received: %d\n"), iResult);
AfxMessageBox(strMessageTemp);
}
else if ( iResult == 0 )
AfxMessageBox(_T("Connection has been gracefully closed\n"));
else
{
strMessageTemp.Format(_T("recv failed: %d\n"), WSAGetLastError());
AfxMessageBox(strMessageTemp);
} } while( iResult > 0 );
}
break; default:
break;
}
// Receive until the peer closes the connection
return 1;
}结果:发送成功,接收部分不能触发。请教[happysheepherder],是什么问题?
MFC可以重载pretranslate函数实现
ON_MESSAGE(WM_CLIENT_READCLOSE,OnReadClose)你有没有消息映射
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_MESSAGE(WM_SOCKET, OnSocket)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()