问题
It says here that the send function expects const char*.
How do I send wide characters? I tried the following:
void MyClass::socksend(const wchar_t* wbuffer) {
int i;
char *buffer = (char *)malloc( MB_CUR_MAX );
wctomb_s(&i,buffer, MB_CUR_MAX, (wchar_t)wbuffer);
int buflen = strlen(buffer) + 2;
char sendbuf[DEFAULT_BUFLEN];
strcpy_s(sendbuf,buflen,buffer);
sendbuf[buflen - 1] = '\n';
int senderror = send(this->m_socket, sendbuf, buflen, 0);
// error handling, etc goes here...
}
This doesn't do what I expect it to. It doesn't seem to be sending anything to the socket. How do I fix this?
回答1:
Note that I'm not sure of the right way to transfer wide char strings across a socket, so for that part, you're on your own. I do know that it has been described to me as pretty hairy and convoluted. :)
With that in mind, If the other side of the socket is expecting a string of wchar_t, you can use wcslen
to get the length of the string to which wbuffer points, giving you
int senderror = send( this->m_socket, (char *)wbuffer, wcslen( wbuffer ) * sizeof( wchar_t ), 0 );
There are also a few possible bugs in your code. If you need to convert the wchar_t string to multibyte, you should use wcstombs_s instead of wctomb_s. wctombs_s converts one character at a time while wcstombs_s converts a string.
If the resulting string is longer than DEFAULT_BUFLEN
you will end up mangling the string with the '\n' and dropping any data beyond DEFAULT_BUFLEN
in length.
send
does not always send the entire buffer. You need to loop over the call to send until all bytes are sent or you reach some limit in time or retries or your patience.
See here for more guidance.
回答2:
What is a wide character in the first place? It's an integral values wider than 8-bit; this means you will have to handle Endianness. You need to encode your wide character array to a char array, and then send it as an char array. In the receiving end, you need to decode the char array to wide character array.
The function wctomb_s only encodes a single wide character to char array. The function you're looking to encode a wide character array to char array is wcstombs_s. Correspondingly, to decode use mbstowcs_s.
with error handling ommitted (untested):
void MyClass::socksend(const wchar_t* wbuffer) {
// determine the required buffer size
size_t buffer_size;
wcstombs_s(&buffer_size, NULL, 0, wbuffer, _TRUNCATE);
// do the actual conversion
char *buffer = (char*) malloc(buffer_size);
wcstombs_s(&buffer_size, buffer, buffer_size, wbuffer, _TRUNCATE);
// send the data
size_t buffer_sent = 0;
while (buffer_sent < buffer_size) {
int sent_size = send(this->m_socket, buffer+buffer_sent, buffer_size-buffer_sent, 0);
buffer_sent += sent_size;
}
// cleanup
free(buffer);
}
来源:https://stackoverflow.com/questions/4350259/how-do-i-send-wide-characters-using-winsocks-send-function