pikmin
pikmin

Reputation: 43

Socket communication between Java and C++

I'm trying to have a connection between a Java server and a C++ client. But when I read the data in my client I always have the same strange character (’). I tried to change the encoding in both side but nothing work.

Here is my Java code :

public class Serveur
{
    public static void main(String[] args) throws Exception
    {
        final int PORT = 13370;
        try
        {
            ServerSocket service= new ServerSocket(PORT);
            Socket connection = service.accept();
            PrintWriter pw = new PrintWriter(connection.getOutputStream());
            String s = Integer.toString(5);
            while(true)
            {
                pw.print(s.getBytes("UTF-8"));
                pw.flush();
                pw.close();
            }
            connection.close();
        }
}

I also tried to use an OutputStream, a DataOutputStream and a BufferedOutputStream.

And here is the C++ code :

int main(int argc, char* argv[])
{
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2,0), &WSAData);
    SOCKET sock;
    SOCKADDR_IN sin;
    char buffer[512];
    sin.sin_addr.s_addr = inet_addr("127.0.0.1");
    sin.sin_family      = AF_INET;
    sin.sin_port        = htons(13370);
    sock = socket(AF_INET,SOCK_STREAM,0);
    if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
{
    cout<<"connection"<<endl;
    if(recv(sock, buffer, sizeof(buffer), 0) != SOCKET_ERROR)
    {
        string s = buffer;
        wchar_t *pwchello = L"Hi";
        wchar_t *pwc      = (wchar_t *)malloc( sizeof( wchar_t ));
        char    *pmbhello = buffer;
        int i = mbstowcs(pwc,pmbhello, MB_CUR_MAX);
        cout << i << endl;
        cout<<"cout : "<<pwc<<endl;
        cout <<buffer<<endl;
        printf("printf : %s\n", buffer);

        cout << "wsagetlasterror() : "<<WSAGetLastError();
        closesocket(sock);
        WSACleanup();
        free(m_pBuffer);
    }
    return 0;
}

As you can see, I tried different solution but without success.

Thanks in advance, and sorry for my english it may be not very good

Upvotes: 4

Views: 13983

Answers (4)

Ahmet Cemil Sabır
Ahmet Cemil Sabır

Reputation: 101

I have been having the same problem since last night. Finally figured out that encoding is not recognized by my server (written in C). Therefore, I changed in my client

someOutputStream.writeUTF(someSillyString);

to

someOutputStream.write(someSillyString.getBytes());

This way, I did not even need to typecast on the server side.

Upvotes: 0

Rob K
Rob K

Reputation: 8926

You're only allocating room for a single wchar_t here:

wchar_t *pwc = (wchar_t *)malloc( sizeof( wchar_t ));

You also assign buffer to string s, but never seem to use s

Upvotes: 0

Andr&#233; Caron
Andr&#233; Caron

Reputation: 45239

You are mixing up lots of different encoding conversions and I/O strategies. You should try out the following simplified version:

if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
{
    cout << "connection" << endl;

    // the result of 'recv()' is either SOCKET_ERROR or
    // the number of bytes received.  don't though away
    // the return value.
    const int result = recv(sock, buffer, sizeof(buffer), 0);
    if(result != SOCKET_ERROR)
    {
        // use length (in bytes) returned by 'recv()'
        // since buffer is not null terminated.
        string s(buffer,result);

        // 's' is in UTF-8 no converstion to wide strings
        // should be necessary.
        cout << "message: '" << s << "'." << endl;
    }

    closesocket(sock);
}
WSACleanup();

However, note that the standard output is in the current code page and usually UTF-8 is not the default code page. Outputing Unicode data to the console in windows requires a few other library calls to configure.

Upvotes: 2

user3458
user3458

Reputation:

recv does not turn its destination buffer into null-terminated string. It fills in a number of bytes in the buffer, but does not append a 0.

You need top do this (with error checking, of course):

ssize_t bytesRead = recv(buffer, ...);
string str(buffer, bytesRead);

Also, be aware that recv does not guarantee that something sent in one call gets received in one call (unless you're doing UDP).

Upvotes: 2

Related Questions