如何使用winsock的send()函数发送宽字符?

发布于 2024-10-06 07:05:34 字数 625 浏览 5 评论 0原文

它说这里发送函数需要const字符*。

如何发送宽字符?我尝试了以下操作:

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

}

这没有达到我的预期。它似乎没有向套接字发送任何内容。我该如何解决这个问题?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

2024-10-13 07:05:34

首先什么是宽字符?它是一个比8位更宽的整数值;这意味着您必须处理字节顺序。您需要将宽字符数组编码为字符数组,然后将其作为字符数组发送。在接收端,需要将字符数组解码为宽字符数组。

函数 wctomb_s 仅将单个宽字符编码为字符数组。您想要将宽字符数组编码为字符数组的函数是wcstombs_s。相应地,解码使用mbstowcs_s。

省略错误处理(未经测试):

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);
}

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);
}
只为一人 2024-10-13 07:05:34

请注意,我不确定通过套接字传输宽字符字符串的正确方法,因此对于这一部分,您需要自己解决。我确实知道有人向我描述它非常多毛且令人费解。 :)
考虑到这一点,如果套接字的另一端期望的是 wchar_t 字符串,则可以使用 wcslen 来获取 wbuffer 指向的字符串的长度,这

int senderror = send( this->m_socket, (char *)wbuffer, wcslen( wbuffer ) * sizeof( wchar_t ), 0 );

也有几种可能您的代码中的错误。
如果需要将 wchar_t 字符串转换为多字节,则应使用 wcstombs_s 而不是 wctomb_s。 wctombs_s 一次转换一个字符,而 wcstombs_s 转换一个字符串。

如果生成的字符串比 DEFAULT_BUFLEN 长,您最终会用“\n”破坏该字符串,并丢弃长度超过 DEFAULT_BUFLEN 的所有数据。

send 并不总是发送整个缓冲区。您需要循环发送调用,直到发送所有字节,或者您达到时间限制或重试或您的耐心。

请参阅此处获取更多指导。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文