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

本文关键字:之间 通信 Java 套接字 我可以 | 更新日期: 2023-09-27 17:58:48

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

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

主要问题是您需要非常小心地对发送和接收的数据进行编码。这是一对协同工作的程序。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();
        }
    }
}

我想知道如何循环这个方法,以便您可以一次又一次地发送客户端消息。如果你觉得这个有用,请告诉我。我使用ExportAnt脚本在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();
    }
}

Ant脚本:

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

我在这里编码的是的高级改进版本

@damix911代码:https://stackoverflow.com/a/14825061/13883478

is=Socket的输入流

Java端接收数据标签:

ByteArrayOutputStream bs = new ByteArrayOutputStream();
    while (true) {
                            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(received);
                            String tag = received.split("''|")[0];
                            int veri_uzunluk = Integer.parseInt(received.split("''|")[1].replace(">", ""));
                            byte[] buffer = new byte[8192];
                            int read = 0;
                            while (true) {
                                read = is.read(buffer, 0, 8192);
                                bs.write(buffer, 0, read);
                                if (bs.toByteArray().length == veri_uzunluk) {
                                    break;
                                }
                            }
                            System.out.println(bs.toByteArray().length);
                            DataProcess(tag, bs.toByteArray());
                            bs.flush();
                            bs.close();
                            bs = null;
                            bs = new ByteArrayOutputStream();
                            //String neymis = new String(recData,0, veri_uzunluk);
                            //System.out.println(tag + ">>>" + neymis);
                            //
    
                        }

示例过程数据:

private void DataProcess(String label, byte[] dataBuff) {
switch (label.split("''|")[0]) {
                case "<RESIM>":
                    FileOutputStream fs = null;
                    try {
                        fs = new FileOutputStream("C:'TEST.jpg");
                        fs.write(dataBuff, 0, dataBuff.length);
                    } catch (Exception e) {
                    }
                    break;
}

}

C#侧用打包器发送数据:

public void PackerNew(string tag, byte[] data, Socket client, string extra = "null")
        {
            string toSend = $"<{tag}>|{data.Length}|{extra}>"; ;
            int toSendLen = Encoding.UTF8.GetBytes(toSend).Length;
            byte[] toSendBytes = System.Text.Encoding.UTF8.GetBytes(toSend);
            byte[] toSendLenBytes = System.BitConverter.GetBytes(toSendLen);
            client.Send(toSendLenBytes, 0, toSendLenBytes.Length, SocketFlags.None);
            client.Send(toSendBytes, 0, toSendBytes.Length, SocketFlags.None);
            client.Send(data, 0, data.Length, SocketFlags.None);
        }
        
        private void button6_Click(object sender, EventArgs e)
        {
            PackerNew("RESIM", File.ReadAllBytes("TEST.jpg"), clint, "null"); // any byte[] data what you want..
        }