更具体地说,如果计算机有服务器(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();
}
}
蚂蚁脚本:
<?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 回答