c++ - 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 我知道代码有点乱,可以做一些改进。