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