我可以使用套接字在Java和C#之间进行通信吗?

时间:2013-02-12 02:26:56

标签: c# java sockets networking

更具体地说,如果计算机有服务器(java.net.ServerSocket实例),我可以使用C#System.Net.Sockets.Socket实例连接到它吗?

2 个答案:

答案 0 :(得分:26)

主要问题是您需要非常小心您发送和接收的数据的编码。这是一对协同工作的程序。 C#客户端发送一个字符串,首先将其长度作为整数发送,然后发送字符串本身的字节。 Java服务器读取长度,然后读取消息并将输出打印到控制台。然后编写一个echo消息,计算其长度,提取字节并将其发送回C#客户端。客户端读取长度,消息并打印输出。应该有办法避免所有按位的东西,但说实话,我对这些东西有点生疏,特别是在Java方面。

Java服务器:

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();
    }
}

C#客户端:

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();
        }
    }
}

答案 1 :(得分:1)

我知道如何循环使用此方法,以便您可以反复发送客户端消息。如果您觉得此功能有用,请告诉我。我使用Export Ant脚本在Eclipse上构建它。我还将包括蚂蚁脚本

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();
    }
}

蚂蚁脚本:

<?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>