C++ C++;客户端套接字只接收消息的第一个字母
过去几天我一直在解决一个问题。我需要设计一个音乐流应用程序在C++中。但是,我发现很难发送从目录中读取文件时获得的文件名。文件名是“sample.wav”和“sample1.wav”,但客户端每次只接收和输出字母S。虽然如果我从服务器手动发送一个分配给变量的字符串消息,客户机只需查找即可收到它。你能给我指一下正确的方向吗 提前谢谢 服务器端C++ C++;客户端套接字只接收消息的第一个字母,c++,file,sockets,server,streaming,C++,File,Sockets,Server,Streaming,过去几天我一直在解决一个问题。我需要设计一个音乐流应用程序在C++中。但是,我发现很难发送从目录中读取文件时获得的文件名。文件名是“sample.wav”和“sample1.wav”,但客户端每次只接收和输出字母S。虽然如果我从服务器手动发送一个分配给变量的字符串消息,客户机只需查找即可收到它。你能给我指一下正确的方向吗 提前谢谢 服务器端 sockaddr_in hint; hint.sin_family = AF_INET; hint.sin_
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);
}
提示中的sockaddr\u;
hint.sin_family=AF_INET;
hint.sin_port=htons(54000);
hint.sin_addr.S_un.S_addr=INADDR\u ANY;
//对于本地ip:inet\u pton
绑定(监听,(sockaddr*)和提示,sizeof(提示));
//最大打开连接数(SOMAXCONN)
听(听,索马康);
//正在等待连接
客户端中的sockaddr_;
int clientSize=sizeof(客户端);
SOCKET-clientSocket=accept(侦听,(sockaddr*)&client,&clientSize);
SOCKET*client_ptr=&clientSocket;
字符主机[NI_MAXHOST];
//客户端的远程名称
字符服务[NI_MAXSERV];
//客户端连接的端口
零内存(主机,NI_MAXHOST);
//零内存(服务,NI_MAXHOST);
//清理内存
sockList.push_back(&clientSocket);
if(getnameinfo((sockaddr*)&client,sizeof(client),host,NI_-MAXHOST,service,NI_-MAXSERV,0)==0)
{
对于(int i=0;i<2;i++){
int postList=send(clientSocket,mainList.GetSongName(i).c_str(),mainList.GetSongName(i).size()+1,0);
}
}
否则{
inet\u ntop(AF\u inet和client.sin\u addr、host、NI\u MAXHOST);
cout您使用的字符串构造函数不正确
cout << "Server >>" << string(buffer, 0, welcomemsg) << endl;
cout问题是您在Unicode模式下工作,而结构WIN32_FIND_DATA
是typedef
d到WIN32_FIND_DATAW
,因此songNames[i]=(char*)数据。cFileName;
将wchar\u t
字符字符串重新解释为单字节字符
作为多字节,由whar\t
字符组成的字符串看起来像是以空结尾的1个字符的字符串
作为一个快速而肮脏的修复,将您的服务器项目模式更改为多字节(注意-代码中可能会有更多错误,因此可能需要更多修复才能使其正常工作)
但更好的是,继续使用Unicode模式,调整代码以使用wchar\u t
字符,而不是char
。这意味着将char buffer[]
更改为wchar\u t buffer[]
并在必要时调整大小值。在问题仍然存在的情况下,删除刚刚创建的0将无法输出缓冲区大小。只接收到文件的第一个字母。非常感谢。最后一个问题是,recv函数似乎无法与wchar\t作为缓冲区一起工作,是否有任何解决方法?是的,这是一个定义Winsock API的有效性(当它应该是void*
时,使用char*
)。在这里,您可以安全地将其转换为(char*)
:recv(sock,(char*)缓冲区,sizeof(buffer),0)
不幸的是,我不得不假设cast提供了相同的结果,因为在强制转换缓冲区和打印所需的消息宽版本时使用recv会得到相同的结果。(wcout您必须在songNames[I]=data.cFileName
处修复它。songNames
应该是wstring[]
。非常感谢您!您为我节省了很多搜索时间。
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;
}
cout << "Server >>" << string(buffer, 0, welcomemsg) << endl;
cout << "Server >>" << string(buffer, welcomemsg) << endl;