以下为转发工具代码:
前提:前置机为服务端,app为客户端.以下代码可以直接用,如果前置机和app都是客户端,则需要改转发工具总的客户端端为服务端,即可.
该转发工具的应用场景:
1.当手机需要通过USB连接前置机的,并采用socket通信的时候使用
应用原理:
就是建立双向通道, 转发工具其实就是两个服务端或者一个客户端一个服务端拼接起来,建立双向通信通道,供连接的两端进行数据流交互使用.
package com.pemt.sockettools;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
ServerSocket serverSocket1 =null;
Socket socket1 =null;
int inputPort=1234;
int outPutPort=3131;//和掌机连接的端口
InetAddress address1 =null;
InetAddress address2 =null;
private static final String TAG = "MainActivity";
SharedPreferences sp ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sp = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor edit = sp.edit();
edit.putString("exception","");
edit.commit();
init();
}
private void init() {
initView();
sp = PreferenceManager.getDefaultSharedPreferences(this);
Log.e(TAG, "init:-------------------------------------- " );
run();
}
private void run() {
new Thread(new Runnable() {
Socket socket2=null;
@Override
public void run() {
try {
socket2 =new Socket("127.0.0.1",1234);//和前置机
Log.e(TAG, "init:----------------------try---------------- ");
// ServerSocket serverSocket2 = new ServerSocket(1234);//和前置机
serverSocket1 =new ServerSocket(outPutPort, 2);//和统一版APP 默认同时连接两个客户端.
Log.e(TAG, "init: 服务端.......");
serverSocket1.setReuseAddress(true); //设置 ServerSocket 的选项
System.out.println("服务器即将启动,等待客户端的链接=====>");
Log.e(TAG, "服务器即将启动,等待客户端的链接=====>" );
//记录客户端的数量
int count = 0 ;
// while (true){
Log.e(TAG, "run: ...........");
socket1 = serverSocket1.accept();//阻塞,等待客户端请求
// socket2 = serverSocket2.accept();//阻塞,等待客户端请求
Log.e(TAG, "等待客户端请求" );
//创建一个新的线程
MyThread serverThread = new MyThread(socket1, socket2,MainActivity.this);
//启动线程
serverThread.start();
count ++ ;
System.out.println("当前客户连接数"+count);
Log.e(TAG, "当前客户连接数"+count);
address1 = socket1.getInetAddress();
Log.d(TAG, "run: socket2=="+socket2);
address2 = socket2.getInetAddress();
System.out.println("当前客户端的ip地址:"+address1.getHostAddress());
Log.e(TAG, "当前客户端的ip地址:"+address1.getHostAddress());
System.out.println("当前客户端的ip地址:"+address2.getHostAddress());
Log.e(TAG, "当前客户端的ip地址:"+address2.getHostAddress());
// }
} catch (IOException e) {
Log.e(TAG, "异常====>"+e );
String str =e+"";
if (str.contains("1234")&& str.contains("refused")){
str+="是否未连接前置机和主站";
}else if(str.contains("BindException")){
str+="端口号被占用!请退出程序,重新登入";
}else if(str.contains("SocketException") && str.contains("Socket closed")){
str+="连接的客户端,超过最大输入,请退出转发工具,重新登录";
}else{
str+="是否未设置统一版APP的usb端口号和IP地址";
}
SharedPreferences.Editor edit = sp.edit();
edit.putString("exception",str);
edit.commit();
e.printStackTrace();
}
}
}).start();
}
EditText et;
EditText client;
Button save;
TextView result;
private void initView() {
et = (EditText) findViewById(R.id.tv1);//和前置机连接的端口
client = (EditText) findViewById(R.id.client);//转发端口
result = (TextView) findViewById(R.id.result);
result.setMovementMethod(ScrollingMovementMethod.getInstance());
save =(Button) findViewById(R.id.save);
save.setOnClickListener(this);
}
@Override
public void onClick(View v) {
String text = et.getText().toString().trim();//和前置连接的端口
String port = client.getText().toString().trim();//和掌机连接的端口
Log.e(TAG, "onClick: "+text+","+port );
if (TextUtils.isEmpty(text) || text == null || TextUtils.isEmpty(port) || port == null){
Toast.makeText(MainActivity.this, "接入端口或转发端口为空,请检查!", Toast.LENGTH_SHORT).show();
Log.e(TAG, "onClick: " +"接入端口或转发端口为空,请检查!");
}else{
inputPort = Integer.parseInt(text);
outPutPort = Integer.parseInt(port);
Toast.makeText(MainActivity.this, "端口保存成功!", Toast.LENGTH_SHORT).show();
Log.e(TAG, "onClick: " + "端口保存成功!");
SharedPreferences.Editor edit = sp.edit();
edit.putString("exception","");
edit.commit();
}
init();
}
@Override
protected void onResume() {
super.onResume();
String exception = sp.getString("exception", "");
result.setText(exception);
}
}
线程
package com.pemt.sockettools;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class MyThread {
//和本线程相关的socket
public Socket socket;
public Socket mSocket02;
private Context mContext;
private SharedPreferences sp;
private static final String TAG = "MainActivity";
public MyThread(Socket socket01, Socket socket02, Context context){
socket = socket01;//和APP的端口
mSocket02 = socket02;//和前置机的端口
mContext = context;
sp = PreferenceManager.getDefaultSharedPreferences(mContext);
}
public void start(){
try {
is1 = socket.getInputStream();//字节输入流 统一版APP-->转发工具
is2 = mSocket02.getInputStream();//和前置机-->转发工具
os1 = socket.getOutputStream();//转发工具--->统一版APP
os2 = mSocket02.getOutputStream();//转发工具--->统一版APP
} catch (IOException e) {
SharedPreferences.Editor edit = sp.edit();
edit.putString("exception","退出程序,请重新登录!");
edit.commit();
e.printStackTrace();
}
ReceiveThread thread =new ReceiveThread();
thread.start();
SendThread sendThread= new SendThread();
sendThread.start();
}
//获取输入流,并读取客户端信息
InputStream is1 = null;
OutputStream os1 = null;
InputStream is2 =null;
OutputStream os2 =null ;
/********************
* thread1 start:
**************************/
private class ReceiveThread extends Thread {
@Override
public void run() {
try {
byte[] buffer1 = new byte[1024 * 20];
//获取输出流
Log.e(TAG, "run: " + "MainActivity");
int len = -1;
while (true) {
while ((len = is1.read(buffer1)) != -1) {//读取统一版APP发过来的字节流
os2.write(buffer1, 0, len);//转发工具的客户端,写给-->前置机
Log.e(TAG, "run:----写往前置机------- " + new String(buffer1, 0, len));
}
int len2 = -1;
os1.flush();
os2.flush();
}
} catch (IOException e) {
SharedPreferences.Editor edit = sp.edit();
edit.putString("exception",e+"");
edit.commit();
e.printStackTrace();
} finally {
//关闭资源
try {
os1.close();
os2.close();
is1.close();
is2.close();
socket.close();
mSocket02.close();
} catch (IOException e) {
SharedPreferences.Editor edit = sp.edit();
edit.putString("exception",e+"");
edit.commit();
e.printStackTrace();
}
}
}
}
/********************thread1 END*****************************/
/********************
* thread2 start:
**************************/
private class SendThread extends Thread {
@Override
public void run() {
try {
byte[] buffer4 = new byte[1024 * 20];
Log.e(TAG, "run: " + "MainActivity");
int len = -1;
String str="";
while (true) {
int len2 = -1;
Log.d(TAG, "run: 开始写往...写给统一版APP");
while ((len2 = is2.read(buffer4)) != -1) {//读取转发工具获取到的输入流
os1.write(buffer4, 0, len2);//转发工具的服务端--->统一版APP
String s = new String(buffer4, 0, len2,"GB2312");
Log.e(TAG, "run:----统一APP---- " + s);
SharedPreferences.Editor edit = sp.edit();
str+=s;
edit.putString("exception",str+"\n");
edit.commit();
}//如果byte数组给的过大,还会刷出来空的byte.
os1.flush();
os2.flush();
}
} catch (IOException e) {
SharedPreferences.Editor edit = sp.edit();
edit.putString("exception",e+"");
edit.commit();
e.printStackTrace();
} finally {
//关闭资源
try {
os1.close();
os2.close();
is1.close();
is2.close();
socket.close();
mSocket02.close();
} catch (IOException e) {
SharedPreferences.Editor edit = sp.edit();
edit.putString("exception",e+"");
edit.commit();
e.printStackTrace();
}
}
}
}
}
/********************thread2 END*****************************/
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:textSize="25dp"
android:text="端口设置"/>
<LinearLayout
android:layout_marginTop="20dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/tv1"
android:background="@drawable/button_shape"
android:layout_width="80dp"
android:text="1234"
android:layout_height="30dp"/>
<TextView
android:layout_marginLeft="10dp"
android:text="接入端口"
android:inputType="number"
android:textColor="@android:color/black"
android:textSize="18dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
<LinearLayout
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/client"
android:background="@drawable/button_shape"
android:layout_width="80dp"
android:text="3131"
android:inputType="number"
android:layout_height="30dp"/>
<TextView
android:layout_marginLeft="10dp"
android:text="转发端口"
android:textColor="@android:color/black"
android:textSize="18dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/save"
android:text="保存"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
<TextView
android:textColor="@android:color/black"
android:textSize="18dp"
android:ellipsize="end"
android:singleLine="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="日志显示"/>
<TextView
android:id="@+id/result"
android:ellipsize="end"
android:scrollbars="vertical"
android:singleLine="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""/>
</LinearLayout>
这是一个用于转发Socket连接的工具,适用于前置机作为服务端,手机APP作为客户端的场景。通过创建双向通信通道,该工具允许手机通过USB与前置机进行Socket通信,实现数据流的交互。
1万+

被折叠的 条评论
为什么被折叠?



