首页 > 解决方案 > C++ 异常套接字行为

问题描述

我正在尝试使用 TCP 服务器 - 客户端连接创建音乐流媒体应用程序。为了实现客户端正在播放的歌曲,我需要从服务器传输特定的数据,例如文件的频道,平均每秒字节数等。从服务器下载歌曲列表或发送hello时连接成功消息,但是,例如,当尝试使用 recv() 函数获取文件的平均每秒字节数时,客户端会在到达该部分时停止。它不接收任何数据,也不继续执行其他命令。

为了更容易理解数据交换的“协议”,客户端程序启动了两个线程,一个将请求发送到服务器(SendRequests 函数),一个接收从服务器发送的数据(接收函数)。由于这个问题没有出现在程序的任何其他部分,我完全不知道该怎么做。

客户端发送请求函数:

DWORD sendRequests = WaitForSingleObject(threadMutex, INFINITE);
_commandType = commandType;

//std::cout << "TYPE: " << _commandType << std::endl;
if (_commandType == 0)
    DefineMenu(1);
else if (_commandType == 1) // sends a hello msg to the server; for testing purposes
{
    char sendString[1024] = "H - Hello from client: ";

    int len = send(_activeSocket, sendString, sizeof(sendString), 0);
    if (len == SOCKET_ERROR)
    {
        std::cout << "len socket error" << std::endl;
        _isActive = 0;
    }
}
else if (_commandType == 2) // requests the most updated list
{
    char sendString[1024] = "L - Requesting the most updated list. \n";
    int len = send(_activeSocket, sendString, sizeof(sendString), 0);
    if (len == SOCKET_ERROR)
    {
        std::cout << "len socket error: " << WSAGetLastError() << std::endl;
        _isActive = 0;
    }
}
// determines if the user chose any number (of a track) from the list to start streaming
else if (_commandType == 3)
{

    if (_storedList.empty() == false)
    {

        int userinput = std::stoi(_userinput);
        bool isIndexed = false;

        for (int i = 0; i < _storedList.size(); i++)
        {
            if (userinput == i)
            {
                isIndexed = true;
            }
        }

        if (isIndexed)
        {
            for (int i = 0; i < _totalCount; i++)
            {
                if (userinput == i)
                {
                    _selectedTrack = _storedList[i];
                    break;
                }
            }

            std::wcout << "You selected: " << _selectedTrack << std::endl;
            std::cout << "Preparing it for playback..." << std::endl;

            std::string select = selectSong(_userinput);

            if (select != "No song") {
                int len = send(_activeSocket, select.c_str(), 1024, 0);

                std::cout << select << std::endl;
                if (len == SOCKET_ERROR)
                {
                    std::cout << "len socket error: " << WSAGetLastError() << std::endl;
                    _isActive = 0;
                }
            }
        }
        else
        {
            std::cout << "Wrong index!" << std::endl;
        }
        //Sleep(1000);
    }
    else
    {
        std::cout << "List is empty." << std::endl;
    }

    //Sleep(1000);
}
else if (_commandType == 4) {
char sendString[1024] = "N - Requesting Audio File Stream. \n";
int len = send(_activeSocket, sendString, sizeof(sendString), 0);
if (len == SOCKET_ERROR)
 {
    std::cout << "len socket error: " << WSAGetLastError() << std::endl;
    _isActive = 0;
 }
}
else
{
    _commandType = 0;
}


ReleaseMutex(threadMutex);

客户端接收功能:

while (_isActive == 1)
{

    try
    {

        if (_commandType == 1)
        {
            char recvMSG[1024];
            int length = recv(_activeSocket, recvMSG, 1024, NULL);
            if (length <= 0)
            {
                std::cout << "\nReceive has failed. Error that occured: " << WSAGetLastError() << std::endl;
                //_isActive = 0;
                break;
                //SendRequests(0);
            }

            std::cout << recvMSG << std::endl;

        }

        if (_commandType == 2)
        {
            wchar_t newList[1024];
            int length = recv(_activeSocket, (char*)newList, 48, NULL);
            if (length <= 0)
            {
                std::cout << "\nReceive has failed. Error that occured: " << WSAGetLastError() << std::endl;
                _isActive = 0;
                break;
            }

            std::wstring serialList = newList;

            std::vector<std::wstring> newVecList = Split(serialList, '|');

            std::cout << std::endl;

            for (int i = 0; i < newVecList.size(); i++)
            {
                std::wcout << "[" << i << "] " << newVecList[i] << std::endl;
                _totalCount += i;
            }

            _storedList = newVecList;
        }
            
        if (_commandType == 3)
        {
            std::cout << "Command 3 has started" << std::endl;

            wchar_t recvMSG[1024];
            //int length = recv(_activeSocket, (char*)recvMSG, 1024, NULL);

            //std::cout << length << std::endl;
            //if (length <= 0)
            if(ReceiveData((char*)recvMSG, sizeof(recvMSG)) == false) //This recv() is the one mentioned above
            {
                std::cout << "\nReceive has failed. Error that occured: " << WSAGetLastError() << std::endl;
                _isActive = 0;
                break;
                SendRequests(0);
            }
            else {
                std::cout << "Warning" << std::endl;
            }

        std::wstring trackInfo = recvMSG;

        std::wcout << trackInfo << std::endl;

            DefineMenu(2);

        }
        if (_commandType == 4) {
            char recvMSG[1024];
            int length = recv(_activeSocket, recvMSG, 1024, NULL);
            if (length <= 0)
            {
                std::cout << "\nReceive has failed. Error that occured: " << WSAGetLastError() << std::endl;
                //_isActive = 0;
                break;
                //SendRequests(0);
            }

            std::cout << "Streaming has started!" << std::endl;

        }
        
    }
    catch (...)
    {
        std::cout << "\nError was Caught: " << WSAGetLastError() << std::endl;
    }
}

接收数据函数:

int bytesreceived = 0; 
while (bytesreceived < totalbytes)
{
    int ReceiveCheck = recv(_activeSocket, data + bytesreceived, totalbytes - bytesreceived, NULL);
    if (ReceiveCheck == SOCKET_ERROR) 
        return false;
    else if (ReceiveCheck == -1) {
        std::cout << errno << std::endl;
    }
    bytesreceived += ReceiveCheck;
}
return true; 

服务器端:

std::cout << "Client Connected!" << std::endl;

while (true)
{
    try
    {
        char recvMSG[1024];
        int packetLength = recv(_clientSocket, recvMSG, sizeof(recvMSG), NULL);
        if (packetLength <= 0)
        {
            std::cout << "Error receiving command: " << WSAGetLastError() << std::endl;
            DeleteServer(this);
            break;
        }

        std::cout << "Client " << int(this) << " sent " << recvMSG[0] << std::endl;

        if (recvMSG[0] == 'H')
        {   
            char _sendString[1024] = "\nHello from WAV streamer!\n";

            std::cout << recvMSG << int(this) << std::endl;
            send(_clientSocket, _sendString, sizeof(_sendString), 0);
        }
        if (recvMSG[0] == 'L')
        {
            _playList = GetTheList();

            std::wstring serialList;

            for (int i = 0; i < _playList.size(); i++)
            {
                serialList = serialList + _playList[i] + L'|';
            }

            std::cout << recvMSG << std::endl;
            std::wcout << serialList << std::endl;
            send(_clientSocket, (char*)serialList.c_str(), sizeof(serialList) + 16, 0);
            std::cout << sizeof(serialList) << std::endl;
        }
        if (recvMSG[0] == '1' || recvMSG[0] == '2') {

            std::cout << "Client requested song: " << recvMSG[0] << " info" << std::endl;
            _playList = GetTheList();

            const size_t cSize = strlen(recvMSG) + 1;
            wchar_t* wc = new wchar_t[cSize];
            mbstowcs(wc, recvMSG, cSize);


            if (((wc == _selectedTrack) || (wc != _selectedTrack)) && (_selectedTrack != L"" || wc != L""))
                //if ( ( (recvMSG == _selectedTrack) || (recvMSG != _selectedTrack)) && (_selectedTrack != L"" || recvMSG != L"") )
            {
                std::string::size_type sz;

                _selectedTrack = wc;
                int point = std::stoi(_selectedTrack, &sz) - 1;
    
                //recvMSG;

                //Call method to get the file size in bytes and prepare it for streaming
                std::wstring name = getFileName(point, "C:\\Users\\User\\Documents\\Storage\\*.wav");

                DirectSoundLoad mainLoader(name);

                std::string trackInfo = "\nFile name: ";

                std::cout << trackInfo;

                std::wcout << name << endl;

                trackInfo = "Average Bytes Per Second:" + std::to_string(mainLoader.getAvgBPS());
                
                std::cout << trackInfo << endl;

                std::string toSend = std::to_string(mainLoader.getAvgBPS());

                std::cout << "Sending message:" << toSend.c_str() << std::endl;
                
                
                //SendData(toSend.c_str(), sizeof(toSend));

                int songData = send(_clientSocket, toSend.c_str(), sizeof(toSend), 0);
            
            }
            else
            {
                std::string trackInfo = "\nSorry, this file doesn't exist in the list anymore.";
                send(_clientSocket, trackInfo.c_str(), 1024, 0);
            }
        }
        recvMSG[0] = '\0';
    }
    catch (...)
    {
        std::cout << "An error has occured." << std::endl;
        break;
    }
    
}

对于这篇长篇文章我感到很抱歉,如果有人能真正帮助我,我将非常感激。

PS 我知道代码有点乱,可以做一些改进。

标签: c++socketstcp

解决方案


推荐阅读