本帖最后由 Dream_Peng 于 2022-11-21 10:15 编辑
我是在proxy一个游戏的时候发生的这个问题,问题描述如下:
先要解释:
1.首先游戏登录 使用端口是127.0.0.1:20000
2.登录成功跳转到角色选择 使用端口是127.0.0.1:20002
我proxy的是该游戏的20000-30000端口,所有地址
步骤如下:
1.在客户端输入账号密码,连接127.0.0.1:20000 进行账号验证
2.登录成功进入角色选择, 断开127.0.0.1:20000 连接 转向127.0.0.1:20002进行连接
3.没然后了,连接127.0.0.1:20002 秒断开。
附上代码部分:
[Java] 纯文本查看 复制代码 public static void main(String[] args) throws IOException {
/**
* [url=home.php?mod=space&uid=952169]@Param[/url] args
*/
ServerSocket serverSocket = new ServerSocket(2233);
while (true) {
Socket socket;
try {
socket = serverSocket.accept();
new SocketThread(socket).start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
下面是SocketThread:
[Java] 纯文本查看 复制代码 private Socket socketIn;
private InputStream isIn;
private OutputStream osIn;
//
private Socket socketOut;
private InputStream isOut;
private OutputStream osOut;
public SocketThread(Socket socket) {
this.socketIn = socket;
}
private byte[] buffer = new byte[4096];
private static final byte[] VER = {0x5, 0x0};
private static final byte[] CONNECT_OK = {0x5, 0x0, 0x0, 0x1, 0x7F, 0x0, 0x0, 0x1, 0x0, 0x0};
public void run() {
String host = "";
int port = 0;
try {
System.out.println(" a client connect " + socketIn.getInetAddress() + ":" + socketIn.getPort());
isIn = socketIn.getInputStream();
osIn = socketIn.getOutputStream();
//获取客户端请求认证数据(版本(长度1)、认证方式数量(长度1)、认证方式(长度1-255))
int len = isIn.read(buffer);
//System.out.println("< " + bytesToHexString(buffer, 0, len));
//此处返回客户端认证方式(版本(长度1)、认证方式(长度1))
osIn.write(VER);
osIn.flush();
//System.out.println("> " + bytesToHexString(VER, 0, VER.length));
//授权通过,客户端请求建立连接(版本(长度1)、请求类型(长度1)、保留字节(长度1)(默认00)、(长度1)客户端地址类型、客户端地址、客户端端口(长度2))
len = isIn.read(buffer);
//System.out.println("< " + bytesToHexString(buffer, 0, len));
// 查找主机和端口
byte cmd = buffer[1];
if (cmd == 1) {
host = findHost(buffer, 4, len - 3);
port = findPort(buffer, len);
System.out.println("link to remote : " + host + ":" + port);
//连接原主机需要连接的地址
socketOut = new Socket(host, port);
isOut = socketOut.getInputStream();
osOut = socketOut.getOutputStream();
//告知客户端已连接成功,并返回
System.out.println(buffer[2]);
byte[] b = HexStrToByteArray("05 00 00 01 7F 00 00 01 " + Integer.toHexString(socketOut.getLocalPort()).toUpperCase());
System.out.println("代{过}{滤}理返回本地数据: " + bytesToHexString(b, 0, b.length));
osIn.write(b);
osIn.flush();
//System.out.println("[client] : " + bytesToHexString(CONNECT_OK, 0, CONNECT_OK.length));
//将客户端请求内容转发给真实目标端
SocketThreadOutput out = new SocketThreadOutput(isIn, osOut);
out.start();
//将真实目标端响应内容转发给客户端
SocketThreadInput in = new SocketThreadInput(isOut, osIn);
in.start();
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("the proxy socket can't connect, " + host + ":" + port);
System.out.println("a client leave");
} finally {
try {
if (socketIn != null) {
socketIn.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static String findHost(byte[] bArray, int begin, int end) {
//将IP地址转10进制 仅支持IPV4
StringBuilder sb = new StringBuilder();
for (int i = begin; i <= end; i++) {
sb.append(0xFF & bArray[i]);
sb.append(".");
}
sb.deleteCharAt(sb.length() - 1);
return sb.toString();
}
public static int findPort(byte[] bArray, int len) {
//将最后两位端口号如:4E 20 转换成十进制 20000
return ByteBuffer.wrap(bArray, len - 2, 2).asShortBuffer().get() & 0xFFFF;
}
/**
* 字节数组转16进制文本
*
* @param bArray 字节数组
* @param begin 开始位置
* @param end 结束位置
* [url=home.php?mod=space&uid=155549]@Return[/url] 16进制文本
*/
public static String bytesToHexString(byte[] bArray, int begin, int end) {
StringBuilder sb = new StringBuilder(bArray.length);
String sTemp;
for (int i = begin; i < end; i++) {
sTemp = Integer.toHexString(0xFF & bArray[i]);
if (sTemp.length() < 2)
sb.append(0);
sb.append(sTemp.toUpperCase());
sb.append(" ");
}
return sb.toString();
}
里面两个方法
[Java] 纯文本查看 复制代码 private InputStream isIn;
private OutputStream osOut;
public SocketThreadOutput(InputStream isIn, OutputStream osOut) {
this.isIn = isIn;
this.osOut = osOut;
}
private byte[] buffer = new byte[4096];
public void run() {
try {
int len;
while ( (len = isIn.read(buffer))!=-1) {
if (len > 0) {
osOut.write(buffer, 0, len);
osOut.flush();
System.out.println("客户端请求: " + bytesToHexString(buffer, 0, len));
}
}
} catch (Exception e) {
System.out.println("SocketThreadOutput leave");
}
}
[Java] 纯文本查看 复制代码 private InputStream isOut;
private OutputStream osIn;
public SocketThreadInput(InputStream isOut, OutputStream osIn) {
this.isOut = isOut;
this.osIn = osIn;
}
private byte[] buffer = new byte[4096];
public void run() {
try {
int len;
while ( (len = isOut.read(buffer))!=-1) {
if (len > 0) {
osIn.write(buffer, 0, len);
osIn.flush();
System.out.println("服务端返回: " + bytesToHexString(buffer, 0, len));
}
}
} catch (Exception e) {
System.out.println("SocketThreadInput leave");
}
}
求教为什么会断开呢?
附上源码,后缀改java即可
Main.java
Main.txt
(628 Bytes, 下载次数: 1)
SocketThread.java
SocketThread.txt
(4.91 KB, 下载次数: 1)
SocketThreadInput.java
SocketThreadInput.txt
(972 Bytes, 下载次数: 1)
SocketThreadOutput.java
SocketThreadOutput.txt
(1002 Bytes, 下载次数: 1)
|