LocalSocket通信跨进程的输入流获取数据问题,客户端输入数据,但是服务端只能完整获取第一个数据,剩余的数据会拼接成一个数据,比如我在客户端输入三个数据:21,21,21,到服务端那里则会变成两个数据:21,2121,请大佬们指教指教
客户端run:

服务端run:

服务端代码:
public class MainActivity extends AppCompatActivity {
private static final String SOCKET_NAME = "com.example.localsocket_maipifu";
private static final String TAG = "MainActivity";
public TextView mTextView;
private LocalServerSocket mServerSocket = null;
private LocalSocket mSocket = null;
private InputStream mInputStream = null;
private EditText mEditText;
private Button mButton;
private Object mObject = new Object();
private OutputStream mOut;
// private int pifu = 10;
static class Pifu {
int shuliang;
public Pifu(int shuliang) {
this.shuliang = shuliang;
}
}
public static Pifu pifu = new Pifu(10);
// 步骤1:(自定义)新创建Handler子类(继承Handler类) & 复写handleMessage()方法
private final Handler mHandler = new Handler(Looper.myLooper()) {
// 通过复写handlerMessage() 从而确定更新UI的操作
@Override
public void handleMessage(Message msg) {
// 根据不同线程发送过来的消息,执行不同的UI操作
// 根据 Message对象的what属性 标识不同的消息
// switch (msg.what) {
// case 1:
// break;
// }
if (pifu.shuliang>=0) {
mTextView.setText("剩余皮肤数:" + pifu.shuliang + "个");
}else {
mTextView.setText("剩余皮肤数:" + 0 + "个");
}
}
};
public static boolean flag = true;
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createServerSocket();
mTextView = (TextView) findViewById(R.id.show);
mButton = (Button) findViewById(R.id.client);
findViewById(R.id.notify).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
synchronized (mObject) {
mObject.notifyAll();
}
flag = false;
}
});
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
mSocket = mServerSocket.accept();
} catch (IOException e) {
e.printStackTrace();
mSocket = null;
}
if (mSocket != null) {
new Thread(new Runnable() {
@Override
public void run() {
accepMsg();//必须在子线程接收消息
}
}).start();
}
}
}
}).start();
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
}
private void client(String key) {
synchronized (mObject) {
if (flag) {
try {
mObject.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
final int w = Integer.valueOf(key);
// 采用继承Thread类实现多线程
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < w; i++) {
synchronized (pifu) {
int n = pifu.shuliang--;
if (pifu.shuliang >= 0) {
Log.i("窗口" + Thread.currentThread().getName(), "卖了第" + n + "个皮肤,剩余皮肤数" + pifu.shuliang);
// 步骤3:创建所需的消息对象
Message msg = mHandler.obtainMessage();
msg.obj = "已结束"; // 消息内存存放
// msg.sendToTarget();
mHandler.sendMessage(msg);
//发送消息,发送数据必须要在这里写入到输出流中
if (i>=0){
try {
String com = String.valueOf(Thread.currentThread().getName()+"==>"+(i+1));
mOut = mSocket.getOutputStream();
mOut.write(com.getBytes(), 0, com.length());
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
Log.i(TAG, "已售罄");
break;
}
}
try {
Thread.sleep(600);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.d(TAG, "server mOutputStream == " + Thread.currentThread().getName() + "已完成");
}
}).start();
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
private void accepMsg() {
while (true) {
try {
byte[] buffer = new byte[1024];
mInputStream = mSocket.getInputStream();
int count = mInputStream.read(buffer);
String key = new String(Arrays.copyOfRange(buffer, 0, count));
Log.d(TAG, "server mOutputStream == " + key);
if ("stop".equals(key)) {
closeSocketResource();
break;
}
//
client(key);
} catch (IOException e) {
Log.d(TAG, "exception ==" + e.fillInStackTrace().getMessage());
e.printStackTrace();
}
}
}
private void createServerSocket() {
if (mServerSocket == null) {
try {
mServerSocket = new LocalServerSocket(SOCKET_NAME);
} catch (IOException e) {
throw new RuntimeException("error binding to local socket " + e);
}
}
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
public void closeSocketResource() {
closeClient(mInputStream);
closeClient(mSocket);
try {
if (mServerSocket != null) {
mServerSocket.close();
mServerSocket = null;
}
} catch (IOException e) {
Log.d(TAG, "Failed closing ServerSocket = =" + e.fillInStackTrace());
}
}
private void closeClient(Closeable closeable) {
try {
if (closeable != null) {
closeable.close();
closeable = null;
}
} catch (IOException e) {
Log.d(TAG, "Failed closing==" + closeable);
}
}
}
客户端代码:
public class Client extends Activity implements View.OnClickListener {
private static final String SOCKET_NAME = "com.example.localsocket_maipifu";
private static final String TAG = "Client";
private EditText mEditText;
private LocalSocket mSocket;
private OutputStream mOut;
private TextView mTextView;
private InputStream mInputStream = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
connect();
mEditText = (EditText) findViewById(R.id.input_msg);
findViewById(R.id.replay_btn).setOnClickListener(this);
findViewById(R.id.stop_btn).setOnClickListener(this);
new Thread(new Runnable() {
@Override
public void run() {
for (int i =1;i>0;i++){
try {
byte[] buffer = new byte[10240];
mInputStream = mSocket.getInputStream();
int count = mInputStream.read(buffer);
if (count>=0) {
String key = new String(Arrays.copyOfRange(buffer, 0, count));
Log.i(TAG, "已购买" + key + "个皮肤");
}
} catch (IOException e) {
Log.d(TAG, "exception ==" + e.fillInStackTrace().getMessage());
e.printStackTrace();
}
try {
Thread.sleep(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
private boolean connect() {
if (mSocket != null) {
return true;
}
try {
mSocket = new LocalSocket();//创建LocalSocket,模拟客户端
LocalSocketAddress address = new LocalSocketAddress(SOCKET_NAME,
LocalSocketAddress.Namespace.ABSTRACT);
mSocket.connect(address);//连接LocalSocketServer
} catch (IOException ex) {
return false;
}
return true;
}
private boolean writeCommand(String cmdString) {
final byte[] cmd = cmdString.getBytes();
final int len = cmd.length;
try {
mOut = mSocket.getOutputStream();
mOut.write(cmd, 0, len);
Log.i(TAG, "ClientActivity write " + new String(cmd));
} catch (IOException ex) {
Log.e(TAG, "ClientActivity write error:" + ex.fillInStackTrace());
return false;
}
return true;
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.replay_btn:
writeCommand(mEditText.getText().toString());
// finish();
mEditText.setText("");
// mSocket = null;
// connect();
break;
case R.id.stop_btn:
writeCommand("stop");
break;
default:
break;
}
}
}
请哪位大佬指导一下
这一点问题都没有呀。
数据的传输其实是可以的,只是你可能需要定义一个协议。
比如说你自己都知道用stop来做为结束咯。
以此作为思想,你可以用井号,或者逗号作为数据段的分割。
你读取数据时一个一个字节读,然后判断头和尾,一个头开始,一个尾结束,这样子一条完整的指令就有了了。接下来就是解析指令。