How do I send wide characters using winsock's send() function?

谁说我不能喝 提交于 2020-01-04 14:04:33

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!