javaSocket与C#通信中中文乱码问题的解决方案

  最近正在做一个项目,其中遇到了一个问题就是java与.NET之间的通信问题。具体的问题是这样的:

  客户端使用java,服务器端使用的是C#。两者之间使用基于TCP的Socket通信方式。可是,做了一个测试小例子,结果从客户端传过来的都是乱码。于是上网查,希望可以找到解决方法,可是,网上有好多的答案,经过了很多的实验,都不能很好的解决。没办法只能靠自己一点一点的排查了。

  经过一番努力,最终找到了原因:C#和java的编码方式不同。虽然找到了原因,但是网上关于这个问题的答案也是百家争鸣,在这里就给出源代码,希望对大家有帮助。

  首先是客户端的java代码(这是比较简单的部分)

  

  import .*;import java.io.*;

  public class TCPCline{public static void main(String[] args) throws Exception{try{//这里的IP地址是服务器的IP地址,端口号和服务器统一Socket s = new Socket(“IP地址”,端口);OutputStream os = s.getOutputStream();DataOutputStream dos = new DataOutputStream(os);String sendStr = “你好!hello”;//注意这里,getBytes()中的”UTF-8″byte[] bs = sendStr.getBytes(“UTF-8”); //这里使用的是write(),不是writeUTF(),至于为什么,可以查看java帮助文档,里面讲解了dos.write(bs,0,bs.length);//这里没有使用下面两句,是因为,当我们关闭客户端的时候,在服务器端也可以记录是哪一个客户端掉线了//dos.close();//s.close();}catch(ConnectException connExc){connExc.printStackTrace();}catch(IOException e){e.printStackTrace();}}}

  C#的服务器端代码,在这里说明一下,我们把服务器端的代码放到了一个类库TCPServer中

  下面是错误日志类代码(客户端发送的消息,以及掉线通知都放到这里)

  

  using System.Collections.Generic;using System.Linq;using System.Text;using System;

  namespace TCPServer{ /// <summary> /// 错误日志类 /// </summary> public class LogHelper { public static readonly object objLock = new object(); /// <summary> /// 将错误写入.log文件下 /// </summary> /// <param name=”msg”>错误信息</param> /// <param name=”ex”>异常</param> public static void Err(string msg, Exception ex) { string s = “”; if (ex != null) { s = “err:” + msg + “:” + ex.Message; } else { s = msg ; } //将错误输出到log文件中 string filename = AppDomain.CurrentDomain.BaseDirectory + “log/” + Convert.ToString(getUnixTime()) + “.log”; lock (objLock) { using (System.IO.StreamWriter sw = new System.IO.StreamWriter(filename, true)) { sw.WriteLine(s); if (ex != null) { sw.WriteLine(ex.StackTrace); } sw.WriteLine(“time:” + DateTime.Now.ToString()); sw.WriteLine(“———————————-“); } } }

  ServerListen类

  

  using System.Collections.Generic;using System.Linq;using System.Text;using System.Net;using System.Net.Sockets;using System.Threading;using System;

  namespace TCPServer{ public class ServerListen { public static void Run(Object iGetClientData) { IPEndPoint serverIP = new IPEndPoint(IPAddress.Parse(“IP地址”), 端口);//本机预使用的IP和端口 Socket skServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); skServer.Bind(serverIP); skServer.Listen(100);//连接客户端的上限

  while (true) { Socket skClient; try { //当有可用的客户端连接尝试时执行,并返回一个新的socket,用于与客户端之间的通信 skClient = skServer.Accept(); } catch (Exception ex) { LogHelper.Err(“接收用户连接失败 ServerListen.Run Socket.Accept”, ex); continue; }

  ThrClient thrC = new ThrClient(skServer, skClient, (IGetClientData)iGetClientData); Thread t = new Thread(thrC.Run); t.Start(); } } }}

  ThrClient类

  

  using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Net;using System.Net.Sockets;using System.Threading;

  namespace TCPServer{ public class ThrClient { private static readonly StringBuilder sb = new StringBuilder(); private Socket skServer; private Socket skClient; private IPEndPoint clientIP; private IGetClientData iGetClientData;

  //每次接收发送的临时信息 private byte[] sendData;//发送的信息 private byte[] receiveData = new byte[1024];//接收信息 private int receiveN; private int netID; /// <summary> /// ThrClient构造方法 /// </summary> /// <param name=”pSkServer”>服务端</param> /// <param name=”pSkClient”>客户端</param> public ThrClient(Socket pSkServer, Socket pSkClient,IGetClientData iGetClientData) { this.skServer = pSkServer; this.skClient = pSkClient; this.iGetClientData = iGetClientData;

  this.clientIP = (IPEndPoint)this.skClient.RemoteEndPoint; //下面一定要使用UTF8而不能使用Uncode this.sendData = Encoding.UTF8.GetBytes(“success”); try { this.skClient.Send(sendData, sendData.Length, SocketFlags.None);//发送信息 } catch (Exception ex) { LogHelper.Err(“发送第一次连接成功信息 ThrClient.ThrClient Socket.Send”, ex); } }

  public void Run() { while (true) { try { this.receiveN = skClient.Receive(this.receiveData);//接收 if (this.receiveN != 0) { string removeMsg = Encoding.UTF8 .GetString(receiveData, 0, receiveN); iGetClientData.getThread(removeMsg); } } catch (Exception ex) { iGetClientData.getClientIP(((IPEndPoint)skClient.RemoteEndPoint).Address); break; } } } }

  上面是主要的代码,还有一个向外界提供的接口,这里就不贴出来了。

  两种语言之间的通信问题真的是挺令人头疼的,我们这也是通过猜测然后多次实验才找到了答案。所以,就像《大话设计模式》中提到的,不痴迷,不成功。

旅行,有一种苍凉,“浮云游子意,落日故人情”,

javaSocket与C#通信中中文乱码问题的解决方案

相关文章:

你感兴趣的文章:

标签云: