我可以只使用套接字在Java和C#之间进行通信吗
本文关键字:之间 通信 Java 套接字 我可以 | 更新日期: 2023-09-27 17:58:48
更具体地说,如果计算机有服务器(java.net.ServerSocket
实例),我可以使用C#System.Net.Sockets.Socket
实例连接到它吗?
主要问题是您需要非常小心地对发送和接收的数据进行编码。这是一对协同工作的程序。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..
}