我写了这样的一个程序:一个服务器,是多线程的,直接用的winsock写的
客户端用的是MFC的CAnsySocket类写的
现在要做的事情是这样的,连接成功以后服务器向客户端发送一个字符串
客户端接收到这个字符串以后就把它作为一个文件名打开一个新的txt文件
接下来服务器执行一个循环,把0-99这100个数字发送给客户端,100个数字
发送完了以后再发送一个“STOP”字符串,表示发送完毕
客户端执行一个死循环用来接受服务器发来的字符串,每接受到一个字符串
就把这个字符串写到刚才新建的txt文件的新的一行中,当接受到“STOP”时
退出这个死循环
现在的问题是我发送数字时是每次循环发送一个数字,而客户端接受时却把这些
数字统统放在一个字符串内,没有分开!是本来就应该这样还是我的客户端有问题?
程序如下:
服务器端:
DWORD  WINAPI ServerThread(LPVOID pParam)
{ HWND hwndDlg;
char buff[512];
int ID;      //要作为文件名的数字 EnterCriticalSection(&cs_for_ClientID);
ClientID++;
ID = ClientID;
LeaveCriticalSection(&cs_for_ClientID);

hwndDlg = (HWND)pParam;
SOCKET client = RTIServerSocket; _itoa(ID,buff,10);
send(client,buff,strlen(buff),0);//向客户端发送文件名 for(int i = 0;i<100;i++){
EnterCriticalSection(&cs_for_TestData);
_itoa(TestData,buff,10);
TestData ++;           //要发送的数字
LeaveCriticalSection(&cs_for_TestData); send(client,buff,strlen(buff),0);//发送数字
}
         strcpy(buff,"STOP");
send(client,buff,strlen(buff),0);  //发送停止标志
closesocket(client);

SendMessage(hwndDlg,WM_SERVERSOCKET_CLOSED,0,0);
return 0;
}客户端:
void CRTIClientDlg::test()
{
char *pBuf = new char[1025];
int BufSize = 1024;
int RcvdNum;
CString strRecvd,fileName,strWrite; RcvdNum = m_ClientSocket.Receive(pBuf,BufSize);//接受文件名
pBuf[RcvdNum] = NULL;
strRecvd = pBuf;
fileName = strRecvd;
fileName += (".txt");               //转化为全名
CFile file;
file.Open(fileName,CFile::modeCreate|CFile::modeWrite);
while(1){
RcvdNum = m_ClientSocket.Receive(pBuf,BufSize);
if(RcvdNum == 0) break;
if(RcvdNum == SOCKET_ERROR) continue;     
         pBuf[RcvdNum] = NULL;
strRecvd = pBuf;
if(strRecvd == "STOP") break;//写入文件的时候本意是每行写一个数字,执行完毕以后发现所有的都写在一行
//包括"STOP"也写入文件了,可是遇到“STOP”程序应该跳出循环的!
//而且调试的时候发现strWtite的值是“0123456789.........9899STOP"!
//strWrite应该每次只接受一个字符串啊,怎么会都联在一起呢?

                  strWrite = strRecvd;
int i = strRecvd.GetLength();
strWrite += ("\r\n");
int j = strWrite.GetLength();
file.Write(strWrite,strWrite.GetLength());
}

m_ClientSocket.Close();
return;}

解决方案 »

  1.   

    解决办法:
    你在每次send之后清空缓冲池,memset(buff,0,512);
      

  2.   

    TO:yanhuahui
    客户端要不要清空呢?
      

  3.   

    TO:yanhuahui  
    还是没用:(
      

  4.   

    一般对于这种流式连接,都有一个帧的检测问题,就象操作一个文件一样,你得知道记录从何开始,到哪结束。
    对于字符串,一般用'\n'来表示一个字符串结束。
    或者,用类似BSTR的技术,在发送字符串前先发送一个int数据,表示字符串长度。
      

  5.   

    客户端也要清空?接收也是要到缓冲池满的时候接收。而且你用的阻塞接收,当然是放在一起了,你用的是基于哪种socket创建?
      

  6.   

    喔,看到了,SOCKET,你会出现阻塞现象
      

  7.   

    像你这种情况为何不要事件选择模式。WSAEventSelect(),等到有数据到来的事件发生再去接收不是很好?
      

  8.   

    CString类的赋值:
    char  bytemp[5] = "hello";
    CString strTemp = bytemp;
    他的赋值是要将bytemp所在的内存区一直延伸到有0字符为止的所以东东都赋值过去,比如0x11223356以后的内存上的数据为hellosdjfi0,那么strtemp的值为hellosdjfi.
      

  9.   

    1.要SELECT()才能收
    2.最好指定长度
    3.处理的细节不够多