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