【问题标题】:Java Server, C# Client. Sending DataJava 服务器,C# 客户端。发送数据
【发布时间】:2014-04-08 12:35:30
【问题描述】:

所以,我在将数据从 C# 客户端发送到 Java 服务器时遇到了问题。连接正在建立,但我猜我在某个地方搞砸了。

这是服务器端代码

package com.chris.net;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;


public class Server implements Runnable
{
    private String serverName;
    private boolean isRunning;

private ServerSocket serverSocket;
private Socket clientSocket;

public Server(String name, int port)
{
    try 
    {
        this.serverName = name;
        this.serverSocket = new ServerSocket(port);
        this.isRunning = true;
        new Thread(this).start();
    } 
    catch (IOException e) 
    {
        e.printStackTrace();
    }
}

private BufferedReader recv;

public void run()
{
    while(isRunning)
    {
        try 
        {
            clientSocket = serverSocket.accept();
            System.out.println("Client Connected from " + clientSocket.getInetAddress().getHostAddress() + ":" + clientSocket.getPort());

            recv = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

            System.out.println("Data Recieved: " + recv.readLine());

            clientSocket.close();
        }
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    }
}
}

这是客户端代码

lass TCPClient
{
    private TcpClient Client;
    private NetworkStream Stream;

    private Byte[] Data;

    public TCPClient(string address, int port)
    {
        Client = new TcpClient();
        Client.Connect(address, port);

        Stream = Client.GetStream();

        SendData("Test Data");

        while (Client.Connected)
        {

        }
    }

    public void SendData(string message)
    {
        Data = System.Text.Encoding.ASCII.GetBytes(message);
        Stream.Write(Data, 0, Data.Length);

        Console.WriteLine("Sent: {0}", message);
    }
}

服务器注册连接,客户端似乎认为它已经发送了数据,但是我不知道是客户端没有发送数据还是服务器没有接收它。考虑到 Console.Writeline 只是打印出转换为字节的消息,我不知道。

【问题讨论】:

  • 嗨,你有这个问题的最终解决方案吗?我有同样的问题,但我无法得到正确的解决方案:(

标签: c# java sockets


【解决方案1】:

如果您想使用 JSON,请参阅 this 优秀文章,了解让 Java 发送将您的 java 类型序列化为 JSON 的消息以及接收 C# 以将其 Deserealize 为 C# 类型。

Java 中的摘录:

import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import com.google.gson.Gson;

public class GuyServer {
 public static void main(String[] args)
 throws IOException {
      Gson gson = new Gson();
      ServerSocket serverSocket = new ServerSocket(16001);
      System.out.println("Listening on port 16001. " 
              + "Press enter to quit "
              + "after the next connection.");
      while (System.in.available() == 0) {
           Socket socket = serverSocket.accept();
           System.out.println("A client has connected." 
               + " Sending a new Guy down the pipe.");
           PrintWriter out =
               new PrintWriter(socket.getOutputStream(),
                   true);
           Guy guy = Guy.getRandomGuy();
           String json = gson.toJson(guy);
           out.print(json);
           out.close();
           socket.close();
       }
      System.out.println("Quitting...");
      serverSocket.close();
  }
}

C#结束:

using System;
using System.IO;
using System.Net.Sockets;
using System.Web.Script.Serialization;

class GuyClient
{
     static void Main(string[] args)
     {
          String input;

          using (TcpClient tcpClient = 
                  new TcpClient("localhost", 16001))
          using (NetworkStream networkStream = 
                  tcpClient.GetStream())
          using (StreamReader streamReader = 
                  new StreamReader(networkStream))
          {
               input = streamReader.ReadToEnd();
           }

          Console.WriteLine("Received data: " + input + "\n");

          JavaScriptSerializer javaScriptSerializer = 
                  new JavaScriptSerializer();
          Guy bob = javaScriptSerializer
                  .Deserialize<Guy>(input) as Guy;
          Console.WriteLine(bob.ToString());
      }
}

Java 类

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class Guy {
     private String name;
     public String getName() {
          return name;
      }     
 }

}

C# 可序列化类

using System;
using System.Collections.Generic;

[Serializable]
class Guy
{
     public string Name { get; set; }    
}

我稍微整理了一下,以便更容易理解。它不会编译,但你明白了。

【讨论】:

    【解决方案2】:

    C# TCP 客户端:(这更新了第一个答案),注意到在 C# 中使用 BinaryWriter 类似于 Java 中的 DataOutputStream

    在代码中的某处定义 MAX_BUFFER_SIZE=1024 (example) 的常量!

    public static void WriteString(BinaryWriter os, string value)  {
                if (value!=null) {
                    byte[] array = System.Text.Encoding.Unicode.GetBytes(value);
                    WriteBuffer(os,array);
                } else {
                    WriteInt(os,0);
                }
            }
    
    public static void WriteBuffer(BinaryWriter os, byte[] array) {
                if ((array!=null) && (array.Length > 0) && (array.Length < MAX_BUFFER_SIZE)) {
                    WriteInt(os,array.Length);
                    os.Write(array);
                } else {
                    WriteInt(os,0);
                }
            }
    
    public static void WriteInt(BinaryWriter outStream, int value)  {
                byte[] buffer = BitConverter.GetBytes(value);
                //  Array.Reverse(buffer);
                outStream.Write(buffer);
            }
    

    【讨论】:

    • 把这一切放在一起后,执行以下操作:WriteString(bw, "hello world");结果:h[]e[]l[]l[]o[] []w[]o[]r[]l[]d
    【解决方案3】:

    Java TCP 客户端:您应该分别使用DataInputStreamDataOutputStream 来发送和接收数据:

    try
                        {
                            mOutStream = new DataOutputStream(mClientSocket.getOutputStream());
                            mInStream = new DataInputStream(mClientSocket.getInputStream());
                        }
                        catch (Exception e)
                        {
                            e.printStackTrace();
                        }
    

    操作输出数据流的例子(发送出去):

    public static void WriteString(DataOutputStream os, String value) throws IOException {
            if (value!=null) {
                byte[] array = value.getBytes(CHARSET);
                WriteBuffer(os,array);
            } else {
                WriteInt(os,0);
            }
        }
    
    public static void WriteBuffer(DataOutputStream os, byte[] array) throws IOException {
            if ((array!=null) && (array.length > 0) && (array.length <= MAX_BUFFER_SIZE)) {
                WriteInt(os,array.length);
                os.write(array);
                //os.flush();
            } else {
                WriteInt(os,0);
            }
        }
    
    public static void WriteInt(DataOutputStream os, int value) throws IOException {
            byte[] intAsBytes = ConvertIntToBytes(value);
            os.write(intAsBytes);
            //os.flush();
        }
    

    使用输入流(接收)的例子:

    public static String ReadString(DataInputStream is) throws IOException {
            String ret=null;
            int len = ReadInt(is);
            if ((len == 0) || (len > MAX_BUFFER_SIZE)) {
                ret = "";
            } else {
                byte[] buffer = new byte[len];
                is.readFully(buffer, 0, len);
                ret = new String(buffer, CHARSET);
            }
            return (ret);
        }
    
    public static int ReadInt(DataInputStream is) throws IOException {
            int ret=0;
            byte[] intAsBytes = new byte[4];
            // this will just block forever...
            is.readFully(intAsBytes);
            ret = ConvertBytesToInt(intAsBytes);
            return (ret);
        }
    
    public static int ConvertBytesToInt( byte[] array) {
            int rv = 0;
            for ( int x = 3; x >= 0; x-- )
            {
                long bv = array[ x ];
                if ( x < 3 & bv < 0 ) // keeping the sign intact???
                    bv +=256;
                //rv *= 256;
                rv = rv << 8;
                rv += bv;
            }
            return rv;
        }
    

    【讨论】:

    • 这是用于从 Java 客户端发送数据,但我是从 C# 客户端发送数据。当使用 DataInputStream 接收数据时,我将如何正确处理(目前正在谷歌搜索)
    • 请看我的下一个答案(为方便起见分开)。除了在 IO lib 中使用差异名称之外,C# 与 Java 没有太大区别。
    猜你喜欢
    • 1970-01-01
    • 2015-12-26
    • 2016-02-23
    • 1970-01-01
    • 2019-02-25
    • 2015-02-17
    • 2015-03-05
    • 1970-01-01
    • 2015-02-10
    相关资源
    最近更新 更多