Java客户端在c#服务器上抛出溢出异常

时间:2016-11-22 16:01:33

标签: java c#

所以我在c#中创建了一个服务器c#和一个客户端,以扩展我使用java客户端的用法,但是当我运行客户端时由于某种原因导致服务器上出现溢出异常,这是c#的代码客户(完美无瑕):

    private static TcpClient T = new TcpClient();
static byte[] SendData;
static X509Certificate2 Cert;
internal static string InitIIP(string Data, string proxyHost = "127.0.0.1", int proxyPort = 9050, string destHost = "ipalbloeis2gf4vo.onion", int destPort = 666)
{
    HttpProxyClient HPC = new HttpProxyClient();
    return "";
}
internal static string Init(string Data, string proxyHost = "127.0.0.1", int proxyPort = 9050, string destHost = "ipalbloeis2gf4vo.onion", int destPort = 666)
{
    Process[] pname = Process.GetProcessesByName("tor");
    if (pname.Length == 0)
        MessageBox.Show("Hmmm, we couldnt see if a tor process is running, make sure it is otherwise server connection will fail, trying to continue.....");
    try
    {
        if (!T.Connected)
        {
            Socks5ProxyClient p = new Socks5ProxyClient();
            p.ProxyHost = proxyHost;
            p.ProxyPort = proxyPort;
            p.ProxyUserName = "";
            p.ProxyPassword = "";
            T = p.CreateConnection(destHost, destPort);
        }
        while (true)
        {
            SendData = Encoding.ASCII.GetBytes(Data);
            byte[] buffer = new byte[4];
            NetworkStream serverStream = T.GetStream();
            buffer = new byte[4];
            buffer = BitConverter.GetBytes(SendData.Length);
            serverStream.Write(buffer, 0, 4);
            serverStream.Flush();
            serverStream.Write(SendData, 0, SendData.Length);
            serverStream.Flush();
            byte[] inbuffer = new byte[4];
            buffer = new byte[4];
            int readBytes = serverStream.Read(buffer, 0, 4);
            int MessageSize = BitConverter.ToInt32(buffer, 0);
            byte[] bufferreader = new byte[MessageSize];
            readBytes = serverStream.Read(bufferreader, 0, MessageSize);
            return Encoding.ASCII.GetString(bufferreader);
        }
    }
    catch (Exception ex)
    {
        return null;
    }
}

}

这是相同的代码,但对于我的java客户端:

static Proxy tor = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("127.0.0.1", 9050));
private static Socket s = new Socket(tor);
static InetSocketAddress SERVERADDR = InetSocketAddress.createUnresolved("ipalbloeis2gf4vo.onion", 666);
static byte[] SendData;
public static String Do(String Data)
{
    try
    {
        if(!s.isConnected())
            s.connect(SERVERADDR);
        while(true)
        {
            SendData = Data.getBytes();
            byte[] buffer = new byte[4];
            DataOutputStream serverStream = new DataOutputStream(s.getOutputStream());
            DataInputStream serverInStream = new DataInputStream(s.getInputStream());
            buffer = new byte[4];
            buffer = BitConverter.GetBytes(SendData.length);
            serverStream.write(buffer, 0, 4);
            serverStream.flush();
            serverStream.write(SendData, 0, SendData.length);
            serverStream.flush();
            buffer = new byte[4];
            int readBytes = serverInStream.read(buffer, 0, 4);
            int MessageSize = BitConverter.ToInt32(buffer, 0);
            byte[] bufferreader = new byte[MessageSize];
            readBytes = serverInStream.read(bufferreader, 0, MessageSize);
            return new String(bufferreader);
        }
    }
    catch(Exception e)
    {
        JOptionPane.showMessageDialog(null, "Connection Failed" + e.getMessage(), "Status", JOptionPane.INFORMATION_MESSAGE);
        return "ERR";
    }
}

这是处理客户端连接的服务器上的函数:

private void Do()
    {
        int requestCount = 0;
        string serverResponse = null;
        string rCount = null;
        string dataFromClient = null;
        Byte[] sendBytes = null;
        requestCount = 0;
        Responder.Responder R = new Responder.Responder();
        while ((true))
        {
            try
            {
                byte[] buffer = new byte[4];
                requestCount = requestCount + 1;
                NetworkStream networkStream = clientSocket.GetStream();
                //networkStream.AuthenticateAsServer(ServerCertificate.Servercertificate(), false, SslProtocols.Tls12, true);
                buffer = new byte[4];
                int readBytes = networkStream.Read(buffer, 0, 4);
                if (readBytes == 0)
                    break;
                int MessageSize = BitConverter.ToInt32(buffer, 0); //this throws the exception
                byte[] bufferreader = new byte[MessageSize];
                clientSocket.ReceiveBufferSize = MessageSize;
                readBytes = networkStream.Read(bufferreader, 0, MessageSize);
                Console.WriteLine(Convert.ToString(MessageSize));
                rCount = Convert.ToString(requestCount);
                dataFromClient = Encoding.ASCII.GetString(bufferreader);
                byte[] outbuffer = new byte[4];
                serverResponse = R.Respond(dataFromClient, K, clientSocket);
                sendBytes = Encoding.ASCII.GetBytes(serverResponse);
                outbuffer = new byte[4];
                outbuffer = BitConverter.GetBytes(sendBytes.Length);
                networkStream.Write(outbuffer, 0, 4);
                networkStream.Flush();
                clientSocket.SendBufferSize = sendBytes.Length;
                MessageBox.Show(serverResponse);
                networkStream.Write(sendBytes, 0, sendBytes.Length);
                networkStream.Flush();
            }
            catch (Exception ex)
            {
                EndPointHandler.RemoveEndPoint(clientSocket);
                clientSocket.Close();
                Console.WriteLine("User Server >> " + ex.ToString());
                Thread.CurrentThread.Abort();
            }
        }
        EndPointHandler.RemoveEndPoint(clientSocket);
        Console.WriteLine("User Server >> " + "Client No:" + Convert.ToString(clNo) + " Stopped!");
    }

Exact Exception消息:System.OverflowException:算术运算导致溢出。

我看了谷歌但无法找到解决方案

1 个答案:

答案 0 :(得分:2)

可能是字节序问题

组织字节有两种主流方式;小端和大端:

enter image description here

简而言之,您似乎正在将两者混合在一起。 Java是大端,.NET是通常小端(据我所知,它没有严格指定它应该是什么)。当C#尝试读取从Java发送的大端数时,你最终会看到随机数字问题。

修复它

确保在两端使用相同的字节顺序。一般避免它的技术是发送字符串而不是原始整数字节。

一个粗略的例子(C#):

// Little endian int -> bytes
public static void GetBytes(int value,byte[] result,int offset){
    result[offset]=(byte)value;
    result[offset+1]=(byte) (value>>8);
    result[offset+2]=(byte) (value>>16);
    result[offset+3]=(byte) (value>>24);
}

// Little endian bytes -> int
public static int ToInt32(byte[] data,int offset){
    return    ( (int) data[offset] ) | 
            ( ( (int) data[offset+1] ) << 8 ) | 
            ( ( (int) data[offset+2] ) << 16 ) | 
            ( ( (int) data[offset+3] ) << 24 );
}

作为额外的注意事项,您的协议易受攻击 - 我可能会因为内存耗尽而导致服务器崩溃。如果您正在设计自定义协议,请注意这些事情。