Java里头字符串默认编码是Unicode,你们用C++写的服务器端解析字符串的时候也是以Unicode格式吗?

解决方案 »

  1.   

    C++中是用下面的代码接收数据的
    void CMsg::Serialize(CArchive& ar)
    {
    if (ar.IsStoring())
    {
    ar << (WORD)m_bClose;
    ar << m_strText;
    }
    else
    {
    WORD wd;
    ar >> wd;
    m_bClose = (BOOL)wd;
    ar >> m_strText;    // 在此诸塞(当收到数据时)
    }
    m_msgList.Serialize(ar);
    }m_strText 为CString 类型通讯协议自然没这么简单,我现在只要求服务器能收到正确的数据,不要诸塞在那
      

  2.   

    服务器端是带_UNICODE参数编译的吗?
      

  3.   

    Unicode格式我不太了解,一般我都同默认的。
      

  4.   

    VC默认不是Unicode的,而Java默认是Unicode的,问题可能出在这里。
      

  5.   

    也就是说你发了Unicode字符串过去,那边却作为Ansi字符串接受。
      

  6.   

    看来是这样了,那Java这边应该如何改哪,请指教
      

  7.   

    我也不是很懂,:P。
    这样试试看:
    m_Writer = new PrintWriter(
        new OutputStreamWriter(m_Socket.getOutputStream(), "ISO-8859-1"), true);
      

  8.   

    不行,还是诸塞,当Java端断开连接时,服务器(C++)端探出错误对话框上说:An attempt was made to access an unnamed file past its end.
      

  9.   

    samsun0335(朝阳) :
    C++端已经不能在做任何更改了
      

  10.   

    我现在也在做这个,不过我做的是java这端(客户端),没碰到这个问题啊,我都是直接放到一个byte[]里面发送的,不过发送之前要进行网络字节序转换!!
    唉,今天发现一个大问题,不知道问题出在哪里(跟你的问题无关),上来看看有没有解决办法!!
      

  11.   

    还是使用String类的getBytes方法把按照ISO-8859-1编码的字节数组取出来,然后构造C++语言能够认识的字符串(即bytes序列外加结尾的'\0')吧。
    另外,不要使用PrintWriter了,就使用更原始的OutputStreamWriter,直接发送Bytes。不过没有C/C++的socket编程基础的话,直接玩Java的socket编程,是会遇到一些困难,好多不懂的地方,好多一开始感觉玩不转的地方,慢慢来吧。
      

  12.   

    不管那C++服务端写得多么简陋,两者之间都隐含着一些约定。。这就是通讯协议。。
    把它先弄清楚吧,,有一点尤其要清醒:TCP层提供是面向连接的可靠数据流服务。。
    比如那边C++程序等待接收回车换行字符,这边却就是不发。。那不阻塞才怪。。
      

  13.   

    Unicode格式我不太了解,一般我都同默认的。
    暑假时做过类似的东西,要通过socket让两个程序通信,要先知道字节顺序
    目前的字节顺序有两类:BIG_ENGIAN和LITTLE_ENDIAN
    c端是用的是LITTLE_ENDIAN,而java使用的是LITTLE_ENDIAN,
    所以你可以在c端做一个转换,或者java端做一个转huan比如:我要在c这边把int转换为big-endian放入流中
    注:小端序就是内存的低地址存放的是数据的高字节,
    可以这么做
    static bool int2str(int n, char *buf)
    {
    buf[0] = char((n & 0xff000000) >> 24buf[1] = char((n & 0x00ff0000) >> 16);
    buf[2] = char((n & 0x0000ff00) >> 8);
    buf[3] = char((n & 0x000000ff));return true;
    }同样你要是想在java端转(把big-endian转为little-endian)
    private void insertIntToByteArray(byte[] data,int i,int offset){
      data[offset]==(byte)(i>>0);
      data[offset+1]=(byte)(i>>8)
      data[offset+2]=(byte)(i>>16)
      data[offset+3]=(byte)(i>>24)
    }
    这样!
    }
      

  14.   

    wjsfr(令狐葱) :
    我发送的东西全是字符串,没有任何数据,而且我也试过用byte[]来发送,但是C++端一收到就诸塞,我跟踪后发现C++端收到的字符串少了前三个字符,后面能够正常结束,C++端收到数据的函数如下:C++中是用下面的代码接收数据的
    void CMsg::Serialize(CArchive& ar)
    {
    if (ar.IsStoring())
    {
    ar << (WORD)m_bClose;
    ar << m_strText;
    }
    else
    {
    WORD wd;
    ar >> wd;
    m_bClose = (BOOL)wd;
                 // 程序在此诸塞,m_strText 少前三个字符 
    ar >> m_strText;    // 在此诸塞(当收到数据时)
    }
    m_msgList.Serialize(ar);
    }我感觉会不会是由于C++端使用的是由 CObject 类派生的 CMsg 类接收数据的问题。我的CMsg类头文件为:
    class CMsg : public CObject
    {
    protected:
    DECLARE_DYNCREATE(CMsg)
    public:
    CMsg();// Attributes
    public:
    CString m_strText;
    BOOL m_bClose;
    CStringList m_msgList;
             
             ......};
      

  15.   

    为什么要用MFC的Serialize呢?楼主很清楚C++ MFC对象串行化与JAVA对象串行化的异同吗?
    同时把几种未知因素混在一起了,欲速而不达。在这种情况下,楼主可以在C++先用基本的SOCKET API接收,确定在通讯上没有问题,
    再进一步做下去
      

  16.   

    普通的字符串在 c++
    和java之间肯定也有编码转换问题
    我同意楼上的建议,你一点一点地确定问题出在什么地方
      

  17.   

    谢谢各位,为题解决了。
    原因是我在服务器端使用了MFC中的CArchive类来接受数据,而CArchive又它自己的接收格式,直接发送的字符串是不符合它的接收格式的,在研究了CArchive的接收格式后,我更改了Java端的发送格式,问题就解决了,下面是我的Java发送代码:  public synchronized boolean SendMsg(String str )
      {
        if (m_Socket == null || m_Writer == null)
          return false;    byte b0 = 0;
        try
        {
          m_Writer.write(GetStringLength(str.length()+1));
          m_Writer.write(str.getBytes());
          m_Writer.write(b0);      m_Writer.write(TypeConvert.short2byte(0));
        }
        catch( IOException ex )
        {
          System.out.println(ex.getMessage());
          return false;
        }
        System.out.println("Send: " + str );
        return true;
      }
      // 得到字符串长度字符表示
      public byte[] GetStringLength( int nLength )
      {
        if( nLength < 255 )
        {
          byte b[] = new byte[1];
          b[0] = (byte)nLength;
          return b;
        }
        else if( nLength < 0xfffe )
        {
          byte b[] = new byte[3];
          b[0] = (byte)0xff;
          b[1] = (byte)nLength;
          b[2] = (byte)(nLength>>8);
         return b;
        }
        else if( nLength < 0xffffffff )
        {
          byte b[] = new byte[7];
          b[0] = (byte)0xff;
          b[1] = (byte)0xff;
          b[2] = (byte)0xff;
          b[3] = (byte)nLength;
          b[4] = (byte)(nLength>>8);
          b[5] = (byte)(nLength>>16);
          b[6] = (byte)(nLength>>24);
        return b;
        }
        else
        {
          byte b[] = new byte[15];
          for( int i = 0; i < 7; i++ )
          {
            b[i] = (byte)0xff;
          }
          b[7] = (byte)nLength;
          b[8] = (byte)(nLength>>8);
          b[9] = (byte)(nLength>>16);
          b[10] = (byte)(nLength>>24);
          b[11] = (byte)(nLength>>32);
          b[12] = (byte)(nLength>>40);
          b[13] = (byte)(nLength>>48);
          b[14] = (byte)(nLength>>56);
         return b;
        }
      }
      public static byte[] short2byte(int n) {
        byte[] b = new byte[2];
        b[0]=(byte)(n>>8);
        b[1]=(byte)n;
        return b;
      }