Can I communicate between Java and C# using just sockets?

前端 未结 2 1502
逝去的感伤
逝去的感伤 2020-12-05 09:04

More specifically, if a computer has a server (a java.net.ServerSocket instance) can I connect to it using a C# System.Net.Sockets.Socket instance?

相关标签:
2条回答
  • 2020-12-05 09:25

    I figure how to loop this method so you can send client message over and over again. Let me know if you found this useful. I build this on Eclipse with Export Ant script. I will include ant script as well

    package lineage;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    
    public class l2protector {
        public static void main(String[] args) throws IOException {
            boolean runserver = true;
            ServerSocket serverSocket = new ServerSocket(1040, 10);
            Socket socket = serverSocket.accept();
            InputStream is = socket.getInputStream();
            OutputStream os = socket.getOutputStream();
            do
            {
                try {
                    serverSocket = new ServerSocket(1040, 10);
                    socket = serverSocket.accept();
                    is = socket.getInputStream();
                    os = socket.getOutputStream();
                    // Receiving
                    byte[] lenBytes = new byte[4];
                    is.read(lenBytes, 0, 4);
                    int len = (((lenBytes[3] & 0xff) << 24) | ((lenBytes[2] & 0xff) << 16) |
                              ((lenBytes[1] & 0xff) << 8) | (lenBytes[0] & 0xff));
                    byte[] receivedBytes = new byte[len];
                    is.read(receivedBytes, 0, len);
                    String received = new String(receivedBytes, 0, len);
                    if(received != null) {
                        System.out.println("Server received: " + received);
                    }
                    // Sending
                    String toSend = "Echo: " + received;
                    byte[] toSendBytes = toSend.getBytes();
                    int toSendLen = toSendBytes.length;
                    byte[] toSendLenBytes = new byte[4];
                    toSendLenBytes[0] = (byte)(toSendLen & 0xff);
                    toSendLenBytes[1] = (byte)((toSendLen >> 8) & 0xff);
                    toSendLenBytes[2] = (byte)((toSendLen >> 16) & 0xff);
                    toSendLenBytes[3] = (byte)((toSendLen >> 24) & 0xff);
                    os.write(toSendLenBytes);
                    os.write(toSendBytes);
                    socket.close();
                }
                catch(Exception e) {
                    serverSocket.close();
                }
                
            }
            while(runserver);
            serverSocket.close();
        }
    }
    

    Ant Script:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!-- WARNING: Eclipse auto-generated file.
                  Any modifications will be overwritten.
                  To include a user specific buildfile here, simply create one in the same
                  directory with the processing instruction <?eclipse.ant.import?>
                  as the first entry and export the buildfile again. --><project name="AntiCheat" default="dist" basedir=".">
        <description>
        simplest example build file
      </description>
        <!-- set global properties for this build -->
        <property name="src" location="src" />
        <property name="build" location="build" />
        <property name="dist" location="dist" />
        <property name="version" value="1.0" />
     
        <target name="init">
            <!-- Create the time stamp -->
            <tstamp />
            <!-- Create the build directory structure used by compile -->
            <mkdir dir="${build}" />
        </target>
     
        <target name="compile" depends="init" description="compile the source">
            <!-- Compile the java code from ${src} into ${build} -->
            <javac srcdir="${src}" destdir="${build}" />
        </target>
     
        <target name="dist" depends="compile" description="generate the distribution">
            <buildnumber />
            <!-- Create the distribution directory -->
            <mkdir dir="${dist}/lib" />
     
            <!-- Put everything in ${build} into the MyApplication-${version}.${build.number}.jar -->
            <jar destfile="${dist}/lib/MyApplication-${version}.${build.number}.jar" basedir="${build}" />
        </target>
     
        <target name="clean" description="clean up">
            <!-- Delete the ${build} and ${dist} directory trees -->
            <delete dir="${build}" />
            <delete dir="${dist}" />
        </target>
    </project>
    
    0 讨论(0)
  • 2020-12-05 09:40

    The main issue is that you need to be very careful with the encoding of the data that you send and receive. Here is a pair of programs that work together. The C# client sends a string, by first sending its length as an integer, and then sending the bytes of the string itself. The Java server reads the length, then reads the message and prints an output to the console. Then composes an echo message, computes its length, extracts the bytes and sends it back to the C# client. The client reads the length, the message and prints an output. There should be a way to avoid all the bitwise stuff, but honestly I'm a little rusty with this stuff, especially on the Java side.

    A Java server:

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class JavaSocket {
    
        public static void main(String[] args) throws IOException {
    
            ServerSocket serverSocket = new ServerSocket(4343, 10);
            Socket socket = serverSocket.accept();
            InputStream is = socket.getInputStream();
            OutputStream os = socket.getOutputStream();
    
            // Receiving
            byte[] lenBytes = new byte[4];
            is.read(lenBytes, 0, 4);
            int len = (((lenBytes[3] & 0xff) << 24) | ((lenBytes[2] & 0xff) << 16) |
                      ((lenBytes[1] & 0xff) << 8) | (lenBytes[0] & 0xff));
            byte[] receivedBytes = new byte[len];
            is.read(receivedBytes, 0, len);
            String received = new String(receivedBytes, 0, len);
    
            System.out.println("Server received: " + received);
    
            // Sending
            String toSend = "Echo: " + received;
            byte[] toSendBytes = toSend.getBytes();
            int toSendLen = toSendBytes.length;
            byte[] toSendLenBytes = new byte[4];
            toSendLenBytes[0] = (byte)(toSendLen & 0xff);
            toSendLenBytes[1] = (byte)((toSendLen >> 8) & 0xff);
            toSendLenBytes[2] = (byte)((toSendLen >> 16) & 0xff);
            toSendLenBytes[3] = (byte)((toSendLen >> 24) & 0xff);
            os.write(toSendLenBytes);
            os.write(toSendBytes);
    
            socket.close();
            serverSocket.close();
        }
    }
    

    A C# client:

    using System;
    using System.Net;
    using System.Net.Sockets;
    
    namespace CSharpSocket
    {
        class MainClass
        {
            public static void Main (string[] args)
            {
                string toSend = "Hello!";
    
                IPEndPoint serverAddress = new IPEndPoint(IPAddress.Parse("192.168.0.6"), 4343);
    
                Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                clientSocket.Connect(serverAddress);
    
                // Sending
                int toSendLen = System.Text.Encoding.ASCII.GetByteCount(toSend);
                byte[] toSendBytes = System.Text.Encoding.ASCII.GetBytes(toSend);
                byte[] toSendLenBytes = System.BitConverter.GetBytes(toSendLen);
                clientSocket.Send(toSendLenBytes);
                clientSocket.Send(toSendBytes);
    
                // Receiving
                byte[] rcvLenBytes = new byte[4];
                clientSocket.Receive(rcvLenBytes);
                int rcvLen = System.BitConverter.ToInt32(rcvLenBytes, 0);
                byte[] rcvBytes = new byte[rcvLen];
                clientSocket.Receive(rcvBytes);
                String rcv = System.Text.Encoding.ASCII.GetString(rcvBytes);
    
                Console.WriteLine("Client received: " + rcv);
    
                clientSocket.Close();
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题