10

より具体的には、コンピューターにサーバー (java.net.ServerSocketインスタンス) がある場合、C#System.Net.Sockets.Socketインスタンスを使用してサーバーに接続できますか?

4

2 に答える 2

32

主な問題は、送受信するデータのエンコードに細心の注意を払う必要があることです。以下は、連携して動作する一対のプログラムです。C# クライアントは、最初にその長さを整数として送信し、次に文字列自体のバイトを送信することによって、文字列を送信します。Java サーバーは長さを読み取り、次にメッセージを読み取り、出力をコンソールに出力します。次に、エコー メッセージを作成し、その長さを計算し、バイトを抽出して 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();
    }
}

AC# クライアント:

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();
        }
    }
}
于 2013-02-12T03:47:10.570 に答える
1

クライアント メッセージを何度も送信できるように、このメソッドをループする方法を理解します。これが便利だと思ったら教えてください。これを、Export Ant スクリプトを使用して Eclipse でビルドします。antスクリプトも含めます

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>
于 2020-06-26T16:42:06.447 に答える