为什么每次send,recv后上次再次执行此操作需要先关闭套接字再连接后才成功

为什么每次send,recv后下次再次执行此操作需要先关闭套接字再连接后才成功?
我封装了套接字,执行获取网页源码的功能

我采取的是tcp协议,阻塞模式的。

这个是我自己定义初始化socket以及连接主机、端口的函数(没问题)
C/C++ code

bInitSocket(CString pHost,//主机,域名
            int nPort)//端口号
{
    //...
    //连接服务器
    if (connect(m_Socket, (sockaddr *)&server, sizeof(server)) == SOCKET_ERROR)
    {
        MessageBox(NULL, "Connect Error!", "Error", 0);
        CloseSocket();
        return FALSE;
    }
    //...
}



这个是我自己封装的发送包的方法(没问题)
C/C++ code

nPostPackage(const CString strPockage)
{
    //....
    //发送数据
    nSend = send(m_Socket, strNewPockage.GetBuffer(0), strNewPockage.GetLength(), 0);
    //...
}



这个是我自己封装的在调用nPostPackage方法后执行接收数据的方法(没问题)
C/C++ code

nGetData()
{
        while (nRet > 0)
    {
                //...
        // 接收返回数据包
        nRet = recv(m_Socket, (LPSTR)arryRecv, sizeof(arryRecv), 0);
                //...
        }
{}



这个是我自己封装的关闭套接字的方法(没问题)
C/C++ code

CloseSocket()
{
        try
    {
        shutdown(m_Socket, 0X02);
        closesocket(m_Socket);
        WSACleanup();
    }
    catch (...)
    {
        MessageBox(NULL, "Close socket fail", "Error", 0);
    }
}




**************************
接下来就是我的问题。
我循环(当循环第一次就能nPostPackage和nGetData成功,但是循环第二次的时候就会nGetData返回0个数据)
C/C++ code

{
    nPostPackage(const CString strPockage);//发送数据包后
    nGetData();//接收数据
}



然后我修改成(这个就能成功执行完所有我的循环)
C/C++ code

{
    bInitSocket(CString pHost,//主机,域名
            int nPort);//端口号//初始化并且连接服务器
    nPostPackage(const CString strPockage);//发送数据包后
    nGetData();//接收数据
    CloseSocket();//关闭套接字
}



问题一:为什么修改成这样之后才能成功?
问题二:因为每循环一次都需要连接和关闭套接字,这样性能急剧下降,有没有什么好的办法可以解决此处的性能问题?我只想使用同一个套接字对象,不想创建多个套接字对象。

谢谢。

------解决方案--------------------
貌似没有releasebuff(),我以前也碰到过这个问题,我是因为发送和接受缓冲区大小设置不一样导致的。
------解决方案--------------------
探讨
然后呢?

引用:

你不知道HTTP协议是短连接么?
每次操作以后服务器close了这个连接

------解决方案--------------------
第一次nGetData()之后,该函数退出没?修改为


C/C++ code

nGetData()
{
        while (true)
    {
                //...
        // 接收返回数据包
        int nRet = recv(m_Socket, (LPSTR)arryRecv, sizeof(arryRecv), 0);
                //...
        if(nRet  > 0)
        {
         //todo
        }
        else()
        {}
      }
{}

------解决方案--------------------
另外一个问题,一般send之前,会在包头添加四个字节,用来表示本次发送包的大小;
同理,recv之后,包头前四个字节可以表示为int,与recv的长度进行比较。
------解决方案--------------------

要知道,一个连接,除了你自己close以外, 服务器也是可以close的。
你返回0,说明就是服务器已经close了啊,所以你必须重新连接。

至于为何服务器会主动close, 你没有说你连的是什么服务器,说以不好说。
如果你连的是HTTP网站,正如cl_gamer所说,HTTP服务器在给你返回数据后,就会close连接。
------解决方案--------------------