C++ style networking

Nov 28, 2011 at 12:21am
Hi everyone, I'm new :)

I made this weekend a chatserver in C++ with Winsock.h. The chatserver is in a cmd window ( for now ).


I followed some tutorials but there were all in C-style. So my code is C-style too. Now I understand everything I want to change all the C-style code into C++-style but this is not working very well.


With the recv(..) function you need a 'char* buffer' .. And I want to work with strings.
When I write text.c_str(), this will return a constant char* but I need a non-constant char*.. How can I receive this?
the third parameter is the length. In every tutorial they use a constant Length.. If I got a text that says: HELLO I only want 5 characters.. How can I change the length that I will receive? Because every text got a different length of characters and I dont want to have a lot of free space. But if I tell I want to receive 5 characters and i wrote HELLO THERE, I need a bigger length, so how can I do this?


And I got a second question.

you got char, wchar_t and TCHAR.
How is that receive function going to work with the koreans that are using wchar_t instead of char... Because that recv function only works with char*
Last edited on Nov 28, 2011 at 12:26am
Nov 28, 2011 at 3:25am
1. Most programmers will const_cast std::string::c_str() and use that (or std::wstring if you need wide chars), but I don't encourage it. Instead, I propose that you use a std::vector<char>.

1
2
3
4
5
6
std::vector<char> myBuffer;
myBuffer.reserve(<the amount of bytes you want to reserve>);
//std::vector checks the boundaries, so one item must be pushed back first.
myBuffer.push_back(' '); //Now the next line is valid and get you your buffer.
char *myBufferPtr = &myBuffer[0];
//use myBufferPtr in the calls to the Windows API functions. 


2. The function recv() is not designed to receive text; it is designed to receive anything. So don't confuse yourself with the fact that it receives the data in a buffer of type char. It does this because in C and C++, char is the 1 byte data type. That's all. If C had the native data type called byte, it would be a buffe of bytes and not of chars. So again: Don't think recv() knows what type of text you're getting because it doesn't!

So recv() will get your message in whatever encoding it was sent: If a Unicode string was sent, you'll get a Unicode string in the char array, and to properly display it, you must memcpy() it into an array of wchar_t, or at the very least, reinterpret_cast the buffer as being of type wchar_t*. Personally I recommend that you always use Unicode strings (std::wstring and related data types). It makes things simpler.

3. Buffer size. You cannot know what buffer size you need ahead of time. You must wait for the function to start receiving data from the socket. Usually the receive buffer is made fixed and relatively small. Once a message is received, a new dynamic buffer is created and filled in a loop where recv() is called while it returns the WSAEMSGSIZE error value (which means there is more data available). Once the function returns no error, it is known that the message is complete and the reading function returns the dynamic buffer to its caller (your upper layers of the chat application).
Nov 28, 2011 at 5:12am
closed account (DSLq5Di1)
I'd recommend resize() instead of reserve(), as the vector will not know how many bytes have been copied into it.
Nov 28, 2011 at 7:35am
I don't want to use a vector with char's..

I'm a game developer ( Well I'm studying Game development ) and my games must be playable for everyone.
There are a lot of Koreans that play games but they work with wide characters.
I there a way so send and receive wide characters?

I would like to do this:

#ifdef _UNICODE
#define tstring wstring
#else
#define tstring string
#endif

So my tstring can be wstring or string. And I need to put all of my data in these tstrings.
Is this possible? So yes, how?
Nov 28, 2011 at 1:52pm
Yes, it is possible to use tstring as you mention, but there's no need. A Unicode build will work OK everywhere in the world.

Why do you hate vectors? As I explained, it is one correct way of having a managed buffer.

Finally: Did you understand my explanation of recv() and why the buffer is of type char? Because it doesn't seem like it. The recv() function receives a memory buffer. You interpret this buffer however you like, including wide strings. Most developers will create a buffer to receive binary data as an array of chars and then interpret the contents however they want using reinterpret_cast or C-style casting. Since this buffer is intended for everything (not just text transfer), the recv() function is impervious to the UNICODE #definition, if that's what you're thinking.
Nov 28, 2011 at 2:35pm
Ok thanks, I think I know how recv() works now. I thought recv wasn't UNICODED and couldn't handle with wide characters. Thanks for explaining!
Nov 28, 2011 at 5:19pm
Just one correction:

webJose wrote:
It does this because in C and C++, char is the 1 byte data type.

Isn't true. char can be more than 1 byte long.
Nov 28, 2011 at 6:27pm
No, it is guaranteed to be 1 byte always. It is in the standard. There was a post in this forum rather recently that showed this.
Nov 28, 2011 at 6:43pm
Quick links: http://en.cppreference.com/w/cpp/language/types . This one states just below the first table the following: "Note: the C++ Standard guarantees that 1 == sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long) <= sizeof(long long).".

http://drj11.wordpress.com/2007/04/08/sizeofchar-is-1/ : It reads: "If you’re not careful you see code like this all the time. sizeof(char) is 1. The standard says so.".
Topic archived. No new replies allowed.