4

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

6
  • Is this C or C++? By the looks of it, it's C, (i.e.: you're using malloc). Commented Dec 22, 2011 at 17:12
  • Is this winapi? maybe you want to tag it as such? In any case for such things it is useful to know how to use tools like wireshark so that you can see what is actually on the wire, to determine which of the programs to look first at. Commented Dec 22, 2011 at 17:13
  • it might be because of UTF-8, I would try ASCII Commented Dec 22, 2011 at 17:15
  • @netcoder Except that this wouldn't compile if it were C. Face it, all of those things you deride as "ugly" are a part of your language of choice. :-) Now "idiomatic" or having proper C++ style is another question... Commented Dec 22, 2011 at 17:19
  • @asveikau: Actually, it wouldn't compile in C++ either. There's a missing }. Commented Dec 22, 2011 at 17:26

4 Answers 4

2

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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).

3 Comments

If I always send a simple integer or a string does it received in one call ? And how can I choose between UDP and TCP ?
TCP delivers a sequence of bytes, while UDP delivers a sequence of packets (arrays of bytes). UDP provides built-in message "boundaries" (a packet is a message, up to 64K bytes delivered as a unit), while with TCP you need to plit the stream into messages at the application level (e.g by treating every 4 bytes as single message or inserting a 0 between messages). TCP is guaranteed delivery: you get every byte in the right sequence or you lose the connection. UDP is permitted to drop packets.
As to sending "simple integer or a string", there are really no guarantees. the smaller is the size of data that you pass to send(), the ore probable that it will be delivered in one recv(). However, it's all about timing and packet boundaries. The data you pass to send() is split into packets to be delivered by IP, and recv() will return the data from all the packets that arrived so far.
0

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

Comments

0

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.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.