socket程序客户端。用单步调试,数据是接收到了,但调用GetDlgItem(IDC_MESSAGE)->SetWindowText(m_disMsg)没有显示接收到的数据。
部分代码:
void CWSN_serverDlg::OnTcpConnect() //tcp客户端连接
{
// TODO: Add your control notification handler code here
if (m_sockType == SOCK_TCP_CLIENT)
{
UpdateData(TRUE);
DWORD servIp;
CString ip;
u_short servPort;
servPort =(u_short) m_tcpRemotePort;
m_tcpRemoteIp.GetAddress(servIp);
m_tcpRemoteIp.GetWindowText(ip);
m_status = "Connecting "+ip;

GetDlgItem(IDC_STATUS)->SetWindowText(m_status);
UpdateData(FALSE); SOCKADDR_IN servAddr;
servAddr.sin_family = AF_INET;
servAddr.sin_addr.S_un.S_addr=htonl(servIp);
servAddr.sin_port = htons(servPort); int conn=connect(m_hostSock,(sockaddr *)&servAddr,sizeof(SOCKADDR_IN));
if(conn==SOCKET_ERROR) ///////////////////////////////////
{
GetDlgItem(IDC_STATUS)->SetWindowText("Connect fail");
AfxMessageBox("_SendMsgThread Connect错误!"+GetError(GetLastError()));
return ;
}
m_status = "Connect to "+ip;
GetDlgItem(IDC_STATUS)->SetWindowText(m_status); DWORD dwThreadId;
m_hThread = CreateThread(NULL, 0, SendAndRecvThread, this,0, &dwThreadId);
CloseHandle(m_hThread); }

}DWORD CWSN_serverDlg::SendAndRecvThread(void *pParam)
{
CWSN_serverDlg *pClient = (CWSN_serverDlg *)pParam;
SOCKET hostSock = pClient->m_hostSock;

FD_SET writefd;
FD_SET readfd; while (1)
{
FD_ZERO(&writefd);
FD_ZERO(&readfd);
FD_SET(hostSock, &writefd);
FD_SET(hostSock, &readfd); int reVal = select(0, &readfd,&writefd, NULL, NULL);
if (SOCKET_ERROR == reVal)
{
AfxMessageBox("select error");
return 0;
}
else if (reVal > 0)
{
if (FD_ISSET(hostSock, &writefd))
{
//调用发送
if (FALSE == pClient->SendMsg())
{
AfxMessageBox("发送失败");
return 0;
}
}
if (FD_ISSET(hostSock, &readfd))
{
if (FALSE == pClient->RecvData())
{
AfxMessageBox("接收失败");
return 0;
}
}
}
Sleep(500);
}
return 0;
}
BOOL CWSN_serverDlg::RecvData()//接收函数
{
char flag[FLAG]={0};
CString ip;
int tag=0;
int nErrCode;
BOOL reVal = TRUE;

char buff[100]={0};
CString msg;
int ret=0;
for(;;)
{
ret=recv( m_hostSock,buff,100,0);
if(ret==0)
break;
m_disMsg+=buff;
AfxMessageBox(m_disMsg);//这儿能提示接收的数据,表明收到了数据
}
GetDlgItem(IDC_MESSAGE)->SetWindowText(m_disMsg);///就是这个地方,程序好像根本就不执行到这,不知道为什么
UpdateData(FALSE); return reVal;
}

解决方案 »

  1.   

    你怎么判断数据接收到了
    m_disMsg里数据正常?
      

  2.   

    从服务端发送数据,AfxMessageBox(m_disMsg),提示框显示数据是正常的,调用
    GetDlgItem(IDC_MESSAGE)->SetWindowText(m_disMsg);
    ///就是这个地方,程序好像根本就不执行到这,不知道为什么
    UpdateData(FALSE);
    后对话框显示不出来数据
      

  3.   

    是不是你根本就没从循环里出来
    把AfxMessageBox(m_disMsg);放到循环外面
      

  4.   

    GetDlgItem(IDC_MESSAGE)->SetWindowText(m_disMsg);
    调试看看m_disMsg的数据正确?
    你的IDC_MESSAGE这个ID正确?
      

  5.   

    程序执行到for循环时,当recv()收到数据时,它能正常执行下面的语句。这时服务端没有发送数据时,循环再一次到ret=recv( m_hostSock,buff,100,0);好像根本没执行。单步调试时,直接退出了,显示对话框,这是什么原因呢?一般情况不是当recv()没收到数据时返回0,在退出循环的。
    for(;;)
    {
    ret=recv( m_hostSock,buff,100,0);
    if(ret==0)
    break;
    m_disMsg+=buff;
    AfxMessageBox(m_disMsg);//这儿能提示接收的数据,表明收到了数据
    }
      

  6.   

    好像是这样,但不知道为什么?把GetDlgItem(IDC_MESSAGE)->SetWindowText(m_disMsg);放循环里就可以了
      

  7.   

    问题在于,for循环中调用recv()后,如果有数据,就接收数据。当没有数据时,好像就阻塞在那儿,等到下次有数据到来时,直接从此处的recv()执行。而不是重新从线程SendAndRecvThread(void *pParam)中调用RecvData(),要怎样才能使recv()不阻塞,当调用recv()没收到数据时,返回0?