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


    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("\n", "");
    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 + "\r"));需要在请求信息msg后面加上一个行结束标志符。
    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+"\n";
    }     
    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#则需要在发送信息的后面手动增加一个行结束标识符"\r"。
    对于服务端的反馈信息有两种反馈方式,一个是println(),一个是write(byte[])。前者是文本的发送,后者是文件的发送。
    在使用print(object)方法对文件发送时,java客户端可是正确的接收数据,而C#客户端却不能,所以才采用了write(byte[])方法进行发送。
    接收数据时,还要对按行发送的文本数据进行去尾处理
    这个处理java和c#一样,只是方法名的大小写不同
    str = str.trim();
    str = str.replaceAll("\r", "");
    str = str.replaceAll("\n", "");


  • 相关阅读:
    模拟出栈
    全排列 next_permutation 用法
    区间覆盖
    BFS GPLT L2-016 愿天下有情人都是失散多年的兄妹
    GPLT L2-014 列车调度
    图的联通分量个数统计(判断图是否联通)
    堆排序 GPLT L2-012 关于堆的判断
    牛客挑战赛 30 A 小G数数
    由树的中后序遍历求树的前层序遍历
    【HDOJ4699】Editor(对顶栈,模拟)
  • 原文地址:https://www.cnblogs.com/kevinGao/p/2294466.html
Copyright © 2020-2023  润新知