none
socket通信 UNICDE字符串的问题! RRS feed

  • 问题

  • socket 通信 UNICODE字符串的话 如果用_tcslen() 获取的大小传送过去显示不正确。

    长度必须 * 2 + 2 后才能正常显示。。怎么解决?为什么?

    按照道理来说 流式传输他应该是不管传送的是个啥玩意的哦。。。我是直接把UNICODE强制转换参数CHAR* 发送,然后在 把接受的数据强制转换为 UNICODE


    …|▌'寔堅蔃の/「≯還寔╪.逞蔃﹖

    2013年2月24日 7:29

答案

  • memcpy_s的第二个参数是目标缓冲区的大小,也就是st_IOEventMsg.ptszIOMsg的字节数。

    你分配给st_IOEventMsg.ptszIOMsg的是TCHAR类型,元素个数为iRet+1,

    那么如果接收端用的是Unicode,他的字节数就是2*(iRet+1) = 2*iRet+2

    把第二个参数改成sizeof(st_IOEventMsg.ptszIOMsg)试试看。


    Damon Zheng
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年3月1日 6:49
    版主
  • // 发送端
    wchar_t buf[] = L"Hello, World";
    send(SOCKET, buf, sizeof(buf), ....);

    // 接收端
    wchar_t buf[MAX_PATH] = {0};
    recv(SOCKET, buf, sizeof(buf), ...);

    不过要注意机器的大小端的问题,如果发送和接收端的大小端不一样,就可能会出现问题。


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.



    2013年2月26日 3:33
    版主

全部回复

  • socket 通信 UNICODE字符串的话 如果用_tcslen() 获取的大小传送过去显示不正确。

    长度必须 * 2 + 2 后才能正常显示。。怎么解决?为什么?

    按照道理来说 流式传输他应该是不管传送的是个啥玩意的哦。。。我是直接把UNICODE强制转换参数CHAR* 发送,然后在 把接受的数据强制转换为 UNICODE

    不要用强制类型转换,不同数据类型的内存占位不一样,会导致数据丢失。

    先用WideCharToMultiByte转为CHAR*类型,传过去之后,再用MultiByteToWideChar转为Unicode宽字符。


    Damon Zheng
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年2月25日 10:06
    版主
  • // 发送端
    wchar_t buf[] = L"Hello, World";
    send(SOCKET, buf, sizeof(buf), ....);

    // 接收端
    wchar_t buf[MAX_PATH] = {0};
    recv(SOCKET, buf, sizeof(buf), ...);

    不过要注意机器的大小端的问题,如果发送和接收端的大小端不一样,就可能会出现问题。


    Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development.



    2013年2月26日 3:33
    版主
  • 是这样的。recv返回的大小。如果我申请了recv返回的大小内存,然后把recv接受到的数据拷贝过去,那么会造成数据丢失,如果直接使用recv接受到的缓冲区。那么就是好的,也就是拷贝的时候大小是不通道饿。

    我接受用的是WCHAR 的缓冲区来接受的!


    …|▌'寔堅蔃の/「≯還寔╪.逞蔃﹖

    2013年2月26日 5:54
  • 是这样的。recv返回的大小。如果我申请了recv返回的大小内存,然后把recv接受到的数据拷贝过去,那么会造成数据丢失,如果直接使用recv接受到的缓冲区。那么就是好的,也就是拷贝的时候大小是不通道饿。

    我接受用的是WCHAR 的缓冲区来接受的!

    可以给出相关的代码吗?把如何“申请recv返回的大小”和“拷贝过去”的代码发上来。

    Damon Zheng
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年2月26日 6:00
    版主
  • int iRet = recv(st_SelectInfo.s,(CHAR *)szBuf,MAX_SELECT_BUF_SIZE,0);

    SOCKETSELECT_IOEVENT st_IOEventMsg = {'\0'};
    memset(&st_IOEventMsg,'\0',sizeof(st_IOEventMsg));

    st_IOEventMsg.nMsgLen = iRet;
    st_IOEventMsg.ptszIOMsg = new TCHAR[iRet + 1];
    memcpy_s(st_IOEventMsg.ptszIOMsg,iRet,szBuf,iRet);

    st_SelectInfo.pSelectSocket->stl_ListIOEvent.push_back(st_IOEventMsg);

    发送端是直接

    LPCTSTR lpszMsg = _T("你是哪个!");
    int nMsgLen = _tcslen(lpszMsg);
    send(socket,lpszMsg,nMsgLen,0)

    这样发送过去的。接受的长度和发送的长度是对的,但是接受后拷贝过去的内容拷贝不全,除非发送端*2 +2 的长度才能拷贝完。。。


    …|▌'寔堅蔃の/「≯還寔╪.逞蔃﹖


    • 已编辑 dowflyon 2013年2月28日 7:36
    2013年2月28日 7:33
  • memcpy_s的第二个参数是目标缓冲区的大小,也就是st_IOEventMsg.ptszIOMsg的字节数。

    你分配给st_IOEventMsg.ptszIOMsg的是TCHAR类型,元素个数为iRet+1,

    那么如果接收端用的是Unicode,他的字节数就是2*(iRet+1) = 2*iRet+2

    把第二个参数改成sizeof(st_IOEventMsg.ptszIOMsg)试试看。


    Damon Zheng
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2013年3月1日 6:49
    版主
  • Unicode转换ANSI:用wcstombs(str_a,str_w,20);
    2013年6月11日 17:39