Reputation: 65
I have been stuck on a problem for the past few days. I need to design a music streaming app in C++. However, I find it difficult to send the file name I get when reading the files from the directory. The file names are "sample.wav" and "sample1.wav" but the client receives and output just the letter S each time. Although if I manually send a string message assigned to a variable from the server, the client receives it just find. Can you point me in the right direction?
Thanks in advance.
Server Side
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(54000);
hint.sin_addr.S_un.S_addr = INADDR_ANY;
// for local ip: inet_pton
bind(listening, (sockaddr*)&hint, sizeof(hint));
// max number of open connections (SOMAXCONN)
listen(listening, SOMAXCONN);
// waiting for connection
sockaddr_in client;
int clientSize = sizeof(client);
SOCKET clientSocket = accept(listening, (sockaddr*)&client, &clientSize);
SOCKET* client_ptr = &clientSocket;
char host[NI_MAXHOST];
// client's remote name
char service[NI_MAXSERV];
// the port on which the client connects
ZeroMemory(host, NI_MAXHOST);
//ZeroMemory(service, NI_MAXHOST);
// cleaning memory
sockList.push_back(&clientSocket);
if (getnameinfo((sockaddr*)&client, sizeof(client), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0)
{
for (int i = 0; i < 2; i++) {
int postList = send(clientSocket, mainList.GetSongName(i).c_str(), mainList.GetSongName(i).size() + 1,0);
}
}
else {
inet_ntop(AF_INET, &client.sin_addr, host, NI_MAXHOST);
cout << host << " connected on port " << ntohs(client.sin_port) << endl;
}
closesocket(listening);
}
Client side:
string ipAddress = "127.0.0.1";
int port = 54000;
WSAData data;
WORD ver = MAKEWORD(2, 2);
int wsResult = WSAStartup(ver, &data);
if (wsResult != 0) {
cerr << "Can't start Winsock, Err #:" << wsResult << endl;
return 0;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
cerr << "Can't create socket. Err #:" << WSAGetLastError << endl;
return 0;
}
sockaddr_in hint;
hint.sin_family = AF_INET;
hint.sin_port = htons(port);
inet_pton(AF_INET, ipAddress.c_str(), &hint.sin_addr);
//hint.sin_addr.S_un.S_addr = INADDR_ANY;
int connResult = connect(sock, (sockaddr*)&hint, sizeof(hint));
bind(sock, (sockaddr*)&hint, sizeof(hint));
if (connResult == SOCKET_ERROR) {
cerr << "Can't connect to Server, Err #:" << WSAGetLastError() << endl;
closesocket(sock);
WSACleanup();
}
char buffer[4096];
string userInput;
ZeroMemory(buffer, 4096);
int msglen;
int numbytes = 0;
int welcomemsg = recv(sock, buffer, sizeof(buffer), 0);
cout << sizeof(buffer) << endl;
cout << "Server >>" << string(buffer, 0, welcomemsg) << endl;
do {
welcomemsg = recv(sock, buffer, 4096, 0);
if (welcomemsg > 0) {
cout << "Server >>" << string(buffer, 0, welcomemsg) << endl;
}
else {
cerr << "Client disconnected" << endl;
}
} while (welcomemsg > 0);
songList object constructor:
wchar_t* w_Path = (wchar_t*)malloc(strlen(filePath) * sizeof(wchar_t));
mbstowcs(w_Path, filePath, strlen(filePath) + 1);
HANDLE hFind;
WIN32_FIND_DATA data;
LPCWSTR m_Path = w_Path;
memset(&data, 0, sizeof(WIN32_FIND_DATA));
hFind = FindFirstFile(m_Path, &data);
if (hFind != INVALID_HANDLE_VALUE) {
int i = 0;
do {
printf("\n %S", data.cFileName);
songNames[i] = (char*)data.cFileName;
i++;
} while (FindNextFile(hFind, &data));
FindClose(hFind);
}
else {
cout << "No songs found in directory" << endl;
}
Upvotes: 2
Views: 324
Reputation: 85361
The problem is you're working in Unicode mode and the struct WIN32_FIND_DATA
is typedef
d to WIN32_FIND_DATAW
, so songNames[i] = (char*)data.cFileName;
reinterprets a string of wchar_t
characters as single-byte characters.
Seen as multi-byte, a string of whar_t
characters looks like a null-terminated string of 1 character.
As a quick-and-dirty fix, change your server project mode to multi-byte (note - there can be more errors in the code, so more fixes might be necessary to make it work).
But better yet, continue using Unicode mode and adjust the code to work with wchar_t
characters instead of char
. That means changing char buffer[]
to wchar_t buffer[]
and adjusting the size values where necessary.
Upvotes: 1
Reputation: 87959
Your use of the string constructor is incorrect
cout << "Server >>" << string(buffer, 0, welcomemsg) << endl;
should be
cout << "Server >>" << string(buffer, welcomemsg) << endl;
Upvotes: 1