Winsock

  • (2 Pages)
  • +
  • 1
  • 2

15 Replies - 1059 Views - Last Post: 31 December 2012 - 04:47 PM Rate Topic: -----

#1 chipicau  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 48
  • Joined: 15-May 12

Winsock

Posted 31 December 2012 - 01:09 PM

Hello.

How do I send special characters through winsock?
Here's my code:

WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);

SOCKET Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
SOCKADDR_IN server_info;
server_info.sin_family = AF_INET;
hostent* host = gethostbyname("myhost.com");
if (host != NULL)
{
	server_info.sin_addr.s_addr = *((DWORD*)host->h_addr);
}
server_info.sin_port = htons(12345);

connect(Socket, (SOCKADDR*)&server_info, sizeof(SOCKADDR_IN));



Until here, everything good, but when I try to send a special character like "ç" or "á", instead it displays this symbol: "�".

CHAR buffer[1024];
strcpy_s(buffer, 1024, "rándom");
send(Socket, buffer, strlen(buffer), NULL);



The receiver would then read "r�ndom".

What am I doing wrong?

Is This A Good Question/Topic? 0
  • +

Replies To: Winsock

#2 jimblumberg  Icon User is online

  • member icon


Reputation: 4013
  • View blog
  • Posts: 12,395
  • Joined: 25-December 09

Re: Winsock

Posted 31 December 2012 - 01:24 PM

Are you sending and receiving on the same computer?

You must also remember that a signed char can only handle values of 0 - 127, what is the numeric value of your "special" character?

Jim
Was This Post Helpful? 1
  • +
  • -

#3 chipicau  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 48
  • Joined: 15-May 12

Re: Winsock

Posted 31 December 2012 - 01:49 PM

Hello jimblumberg.

Yes I am testing both sending and receiving in my own computer, but would there be any difference?

Oh, I didn't know that. In fact, that's probably the issue, because it seems "ç" is 128 and "á" is 160.
Source
So am I out of luck, or is there any other way to send unsigned chars?

Thank you.
Was This Post Helpful? 0
  • +
  • -

#4 chipicau  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 48
  • Joined: 15-May 12

Re: Winsock

Posted 31 December 2012 - 02:14 PM

EDIT:

So, I changed my code to send an unsigned char array like you said, but I still have to convert it to a signed char pointer to send it, so it kind of ruins the purpose :(

unsigned char buffer[1024];
strcpy_s(buffer, 1024, "rándom");
//send(Socket, buffer, strlen(buffer), NULL); this throws an error saying [i]unsigned char*[/i] is incompatible with [i]const char*[/i], so I'm forced to do it like this:
send(Socket, (char*)buffer, strlen((char*)buffer), NULL); //but then it goes back to the same...


Was This Post Helpful? 0
  • +
  • -

#5 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3549
  • View blog
  • Posts: 10,989
  • Joined: 05-May 12

Re: Winsock

Posted 31 December 2012 - 02:25 PM

You also need to consider what charset the receiver is using to display the characters it received. Chances are that it is correctly receiving 128 and 160 for those characters, but you it is displaying using a charset that maps a different glyph for those values.

If you set a breakpoint in the receiver what are the values you are getting in its buffer?
Was This Post Helpful? 1
  • +
  • -

#6 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3549
  • View blog
  • Posts: 10,989
  • Joined: 05-May 12

Re: Winsock

Posted 31 December 2012 - 02:35 PM

Check out CP850 which is what DOS typically uses as compared the Window-1252 which is what US English installations of Windows uses:
CP850: http://en.wikipedia....i/Code_page_850
Windows-1252: http://en.wikipedia....ki/Windows-1252
Was This Post Helpful? 1
  • +
  • -

#7 chipicau  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 48
  • Joined: 15-May 12

Re: Winsock

Posted 31 December 2012 - 02:38 PM

Hey Skydiver.

The thing is, my receiver is coded in C#, so I'm exchanging data between a C# app and a C++ app.
I don't think that's a problem, because everything works fine, except the special characters.

I'm using this code in my C# app to read the buffer:

while (true)
//...
byte[] bytes = new byte[1000000];
int read = tcpclient.GetStream().Read(bytes, 0, bytes.Length);
string data = System.Text.Encoding.UTF8.GetString(bytes, 0, read);
//...



I did what you said (at least what I understood from it) and changed it to:
string data = System.Text.Encoding.ASCII.GetString(bytes, 0, read);



Now the special characters are displayed as interrogation marks: "?".
Was This Post Helpful? 0
  • +
  • -

#8 jimblumberg  Icon User is online

  • member icon


Reputation: 4013
  • View blog
  • Posts: 12,395
  • Joined: 25-December 09

Re: Winsock

Posted 31 December 2012 - 02:38 PM

If you want to send characters with a value greater than 127 then you must cast to an unsigned character, not a signed char and send that unsigned char. You will need to do this on both sides of the transaction.

unsigned char buffer[1024];
// strcpy_s(buffer, 1024, "rándom"); // strcpy() works with signed characters. You may need something else.

send(Socket, (unsigned char*)buffer, strlen((unsigned char*)buffer), NULL); // Again strlen() works with signed char not unsigned. you will probably need something else.



Quote

Yes I am testing both sending and receiving in my own computer, but would there be any difference?

Since you are working on the same computer there should not be a problem of having two different character encodings.

Jim

This post has been edited by jimblumberg: 31 December 2012 - 02:44 PM

Was This Post Helpful? 1
  • +
  • -

#9 chipicau  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 48
  • Joined: 15-May 12

Re: Winsock

Posted 31 December 2012 - 02:45 PM

Hey, jimblumberg.

I tried that, but the problem is that the compiler itself (MSVC++ 2010) refuses to compile, displaying an error:
"argument of type 'unsigned char *' is incompatible with parameter of type 'const char *'".

It seems the Winsock send function will only accept signed chars?
Was This Post Helpful? 0
  • +
  • -

#10 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3549
  • View blog
  • Posts: 10,989
  • Joined: 05-May 12

Re: Winsock

Posted 31 December 2012 - 02:51 PM

Actually, C# defaults to your machines Windows locale. If you are on US English, that will be Windows-1252. If you are using a Microsoft C compiler, I believe that it defaults to CP850 which maps to the "C" locale. (Jim, please jump in if I am mistaken about the default "C" locale.)


Additionally, in your C# code are you calling ASCIIEncoding.GetString() call? (See: http://msdn.microsof...y/744y86tc.aspx ) or some other thing to convert from a byte array to a C#'s internal Unicode string?

Post your C# code for receiving and converting into a string and I maybe able to help you out.

Jim, the Winsock implemenation of send() has the buffer type as const char *, but it will actually send 8-bit bytes stored in the buffer. So the only thing that needs to be done is to cast the parameter to send().

This post has been edited by Skydiver: 31 December 2012 - 03:32 PM

Was This Post Helpful? 1
  • +
  • -

#11 jimblumberg  Icon User is online

  • member icon


Reputation: 4013
  • View blog
  • Posts: 12,395
  • Joined: 25-December 09

Re: Winsock

Posted 31 December 2012 - 02:56 PM

According to the documentation for send(), the buffer should be a cons char* so you may need the const as well.


Why are you using different languages? Why not stick to either C# or C for both the sender and receiver. You will probably have fewer problems if you stick with one or the other. Once you get both working then you can try using the other language on one end or the other.

Jim
Was This Post Helpful? 2
  • +
  • -

#12 chipicau  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 48
  • Joined: 15-May 12

Re: Winsock

Posted 31 December 2012 - 03:04 PM

Hello, Skydiver.

My locale is not US English, it's Portuguese (Europe). I'm compiling my C# code in Microsoft Visual C# 2010.

The code I'm using to receive the data sent by the C++ app is:
while (true)
//...
byte[] bytes = new byte[1000000];
int read = tcpclient.GetStream().Read(bytes, 0, bytes.Length);
string data = System.Text.Encoding.UTF8.GetString(bytes, 0, read);
//...



I tried using
string data = System.Text.Encoding.ASCII.GetString(bytes, 0, read);


to see if it would make any difference, but none at all.



Hello, jimblumberg.
I tried to add the "const" as well, but no avail. :(

And as for why I'm using different languages, I'm doing it because I'm creating a server-client application. I use C# for the server because it's easier and faster to develop a windows form in it, and I use C++ for the client, because C++ doesn't have dependencies.
Was This Post Helpful? 0
  • +
  • -

#13 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3549
  • View blog
  • Posts: 10,989
  • Joined: 05-May 12

Re: Winsock

Posted 31 December 2012 - 03:30 PM

If you know all your clients will be Portuegese, then you can use the Portuguese decoder. For example, see this C# code:
using System;
using System.Data;
using System.Text;

namespace SimpleCsConsole2012
{
class Program
{
    static void Main()
    {
        string input = "Façade Fiancé";

        // Portuguese uses IBM860 code page
        Encoding encoding = Encoding.GetEncoding("IBM860");
        byte[] portugueseBytes = encoding.GetBytes(input);

        Console.WriteLine("Portuguese decode: {0}", encoding.GetString(portugueseBytes));
        Console.WriteLine("UTF8 decode: {0}", new UTF8Encoding().GetString(portugueseBytes));

        Console.ReadLine();
    }
}
}



Notice that decoding the IBM860 encoded bytes as UTF8 causes the question marks that you are reporting.

A better alternative, though is to have the client tell the server what encoding it will be sending data in. Or better yet, always send data in UTF15 to the server. You can use the Windows MultiByteToWideChar() function to convert to UTF16.
Was This Post Helpful? 1
  • +
  • -

#14 jimblumberg  Icon User is online

  • member icon


Reputation: 4013
  • View blog
  • Posts: 12,395
  • Joined: 25-December 09

Re: Winsock

Posted 31 December 2012 - 03:35 PM

I still recommend doing both parts in one language then after you get it done try implementing the client or server functionality in C/C++.

Also if you are planning on using the client on some other operating system you need to remember that unless the other operating system is Windows you won't be able to use your C/C++ code without changes. Winsock is Windows specific, there are differences between it and Posix sockets.

Jim
Was This Post Helpful? 0
  • +
  • -

#15 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3549
  • View blog
  • Posts: 10,989
  • Joined: 05-May 12

Re: Winsock

Posted 31 December 2012 - 03:46 PM

Jim is quite right. Try to stick with one language otherwise you'll be dealing with more issues obscure issues like this.

And if you are targeting Windows only, then .NET 2.0 is guaranteed on Vista and later. If you are thinking of XP, remember that MS support for XP is waning.
Was This Post Helpful? 1
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2