Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
343 views
in Technique[技术] by (71.8m points)

file - C++ Client socket receives only first letter of message

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("
 %S", data.cFileName);
        songNames[i] = (char*)data.cFileName;
        i++;
    } while (FindNextFile(hFind, &data));
    FindClose(hFind);
}
else {
    cout << "No songs found in directory" << endl;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem is you're working in Unicode mode and the struct WIN32_FIND_DATA is typedefd 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...