zoukankan      html  css  js  c++  java
  • java和C#之间SOCKET通信的问题

    转自:http://www.cdtarena.com/javapx/201307/9170.html

      java和C#之间SOCKET通信的问题

      一、服务器端(使用java编写)

      /**

      * 监听客户端的请求

      *

      */

      private static void socketService()

      {

      ExecutorService exec = Executors.newCachedThreadPool();

      try

      {

      ServerSocket server=new ServerSocket(5678);

      int i = 1;

      while(true)

      {

      MyLogManager.InfoLog(log, null,"等待连接第"+i+"个用户...");

      try

      {

      Socket client=server.accept();

      MyLogManager.InfoLog(log, null,"第"+i+"个用户连接完成!");

      exec.execute(new PDAServerWithDB(client));

      }

      catch(Exception whileExp)

      {

      String msg = "多线程处理连接失败!";

      MyLogManager.ErrorLog(log, whileExp, msg);

      }

      i++;

      }

      }

      catch(IOException ioe)

      {

      String msg = "连接失败!";

      MyLogManager.ErrorLog(log, ioe, msg);

      exec.shutdown();

      }

      }

      具体对于Socket信息的接受和发送在PDAServerWithDB类中处理

      信息处理分为:接收数据和发送数据

      服务端接收数据一律采用ReadLine()方法,这就要求客户端在发送请求时要有行结束符。

      服务器的接收发送数据的代码

      a)构造输入输出流

      InputStream inPut = s.getInputStream();

      OutputStream outPut = s.getOutputStream();

      PrintWriter outWriter=new PrintWriter(outPut);

      BufferedReader inputReader =new BufferedReader(new InputStreamReader(inPut));

      b)接收客户端请求的代码

      String request = inputReader.readLine();

      request = request.trim();

      request = request.replaceAll(" ", "");

      c)向客户端发送文本数据的代码

      outWriter.println(strInfo);

      outWriter.flush();

      d)向客户端发送文件的代码

      // 发送文件长度

      File file = new File(filePath);

      byte[] outBytes = new byte[1024];

      int count = 0;

      FileInputStream fileInput = new FileInputStream(file);

      ByteArrayOutputStream ow = new ByteArrayOutputStream();

      while ((count = fileInput.read(outBytes)) > 0) {

      MyLogManager.DebugLog(log, null, String.valueOf(count));

      ow.write(outBytes, 0, count);

      }

      outPut.write(ow.toByteArray());

      //outWriter.print(ow);//这个在JAVA客户端时可以正常响应,而在C#客户端中无法响应。

      //outWriter.flush();

      二、客户端(使用java和c#两个版本)

      1).发送请求信息(字符串格式)

      对于JAVA来说:直接使用PrintWrite类的println()方法即可。

      而对于C#来说:需要使用socket.Send(System.Text.Encoding.ASCII.GetBytes(msg + " "));需要在请求信息msg后面加上一个行结束标志符。http://www.cdtarena.com/php/

      2).接收数据(文本或者文件)

      2-1).java客户端接收数据

      a)java接收文本的代码示例:

      ******代码示例*****

      log.info("开始连接服务器");

      InetAddress address = InetAddress.getByName(AppConfig.IP);//193.100.100.143);

      SocketChannel sc = SocketChannel.open(new InetSocketAddress(address,AppConfig.PORT));

      log.info("服务器连接成功");

      //连接成功 初始化流

      InputStream inputStream = Channels.newInputStream(sc);

      InputStreamReader is = new InputStreamReader(inputStream,"GBK");

      in = new BufferedReader(is);

      log.info("接收服务器的数据");

      String responseLine="";

      while ((responseLine = in.readLine()) != null)

      {

      //用readLine接收数据是,会自动抛弃换行符,如果为了保持数据的格式,需要在这里加上一个换行标识符

      returnStr += responseLine+" ";

      }

      log.info("接收服务器的数据完毕");

      **************

      b)java接收文件的示例代码:

      *****代码示例*****

      log.info("开始连接服务器");

      InetAddress address = InetAddress.getByName("193.100.100.159");//193.100.100.143);

      SocketChannel sc = SocketChannel.open(new InetSocketAddress(address,AppConfig.PORT));

      log.info("服务器连接成功,开始初始化流");

      //连接成功 初始化流

      OutputStream outputStream = Channels.newOutputStream(sc);

      InputStream inputStream = Channels.newInputStream(sc);

      InputStreamReader inputStreamReader = new InputStreamReader(inputStream);

      byte[] b = new byte[1024];

      ByteArrayOutputStream bArrStream = new ByteArrayOutputStream(fileLength);

      int readCount = 0;

      while ((readCount = inputStream.read(b)) != -1)

      {
      log.info(readCount);

      bArrStream.write(b, 0, readCount);

      }

      log.info("size:"+bArrStream.toByteArray().length);

      log.info("接收服务器的数据完毕");

      **************

      2-2.) c#客户端接收数据的代码

      a)接收文本数据

      *****代码示例*****

      Socket socket = null;

      MemoryStream memStream = null;

      string returnMsg = string.Empty;

      //与服务器建立连接

      socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

      IPAddress add = IPAddress.Parse(appConfig.Ip);

      IPEndPoint endPt = new IPEndPoint(add, appConfig.Port);

      socket.Connect(endPt);

      //接收数据

      byte[] buffer = new byte[1024];

      int recCount = 0;

      memStream = new MemoryStream();

      //接收返回的字节流

      while ((recCount = socket.Receive(buffer)) > 0)

      {

      memStream.Write(buffer, 0, recCount);

      }

      Encoding encoding = Encoding.GetEncoding("GBK");

      returnMsg = encoding.GetString(memStream.GetBuffer(), 0, memStream.GetBuffer().Length);

      **************

      b)接收文件数据

      ****代码示例****

      //接收数据

      byte[] buffer = new byte[1024];

      int recCount = 0;

      MemoryStream memStream = new MemoryStream();

      while ((recCount = socket.Receive(buffer)) > 0)

      {

      memStream.Write(buffer, 0, recCount);

      }

      //接下来按照文件格式,将memStream保存为文件即可

      **************

      =======以上是最终使用的代码版本===========

      在开发过程中出现的问题及其解决

      1.)文本乱码问题

      java服务器端代码文件是使用GBK编码。所以在客户端读取的时候使用GBK编码进行转换。

      2.)客户端和服务端的交互。

      在服务端使用PrintWriter类来封装数据发送流(发送数据),new BufferedReader(new InputStreamReader(InputStream))来封装输入流(读取数据)

      服务端读数据的时候是使用ReadLine方法,所以就要求客户端发送请求时需要有一个行结束标志。对于java来说是用println()即可,

      而对于C#则需要在发送信息的后面手动增加一个行结束标识符" "。

      对于服务端的反馈信息有两种反馈方式,一个是println(),一个是write(byte[])。前者是文本的发送,后者是文件的发送。

      在使用print(object)方法对文件发送时,java客户端可是正确的接收数据,而C#客户端却不能,所以才采用了write(byte[])方法进行发送。

      接收数据时,还要对按行发送的文本数据进行去尾处理

      这个处理java和c#一样,只是方法名的大小写不同

      str = str.trim();

      str = str.replaceAll(" ", "");

      str = str.replaceAll(" ", "");

  • 相关阅读:
    erl_0012 timer:tc 测试模块函数调用运行耗时
    erl_0011 erlang 定时器相关
    erl0010
    erl0009
    erl0008
    erl0007
    erl0006
    erl0005
    开开心心过生活、踏踏实实做技术
    Android-理解Intent
  • 原文地址:https://www.cnblogs.com/cdtarena/p/3184313.html
Copyright © 2011-2022 走看看