В моем приложении два человека на разных устройствах подключаются через Wi-Fi одноранговое соединение.Когда они подключены, одному пользователю назначается хост », а другому -« клиент ».
WifiP2pManager.ConnectionInfoListener connectionInfoListener = new WifiP2pManager.ConnectionInfoListener() {
@Override
public void onConnectionInfoAvailable( WifiP2pInfo wifiP2pinfo) {
InetAddress groupOwnerAddress = wifiP2pinfo.groupOwnerAddress;
if (wifiP2pinfo.groupFormed && wifiP2pinfo.isGroupOwner) {
connectionStatus.setText(R.string.host);
new ServerClass().start();
} else if (wifiP2pinfo.groupFormed) {
connectionStatus.setText(R.string.client);
new ClientClass(groupOwnerAddress).start();
}
}
};
Хост выполняет ServerClass, а клиент - ClientClass. Оба они используют класс SendRecieve для отправки каждого из них.другие данные, которые получены через обработчик. Все это прекрасно работает
public class ServerClass extends Thread {
Socket socket;
ServerSocket serverSocket;
@Override
public void run() {
super.run();
try {
serverSocket = new ServerSocket(8888);
socket = serverSocket.accept();
sendReceive = new SendReceive(socket);
sendReceive.start();
} catch (IOException e) {
Log.v("MainActivity", "three" + e);
}
}
}
private class SendReceive extends Thread {
Socket socket;
OutputStream outputStream;
InputStream inputStream;
private SendReceive(Socket skt) {
socket = skt;
try {
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
} catch (IOException e) {
Log.v("MainActivity", "four" + e);
}
}
@Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while (socket != null) {
try {
bytes = inputStream.read(buffer);
//System.out.println(new String(buffer, "UTF8"));
if (bytes > 0) {
handler.obtainMessage(MESSAGE_READ, bytes, -1, buffer).sendToTarget();
}
} catch (IOException e) {
Log.v("MainActivity", "five" + e);
}
}
}
private void write(byte[] bytes) {
try {
outputStream.write(bytes);
} catch (IOException e) {
Log.v("MainActivity", "six" + e);
}
}
}
public class ClientClass extends Thread {
Socket socket;
String hostAdd;
private ClientClass(InetAddress hostAddress) {
hostAdd = hostAddress.getHostAddress();
socket = new Socket();
}
@Override
public void run() {
try {
socket.connect(new InetSocketAddress(hostAdd, 8888), 500);
sendReceive = new SendReceive(socket);
sendReceive.start();
} catch (IOException e) {
Log.v("MainActivity", "seven" + e);
}
}
}
, а затем, когда игра заканчивается, игроки отключаются нажатием кнопки, которая вызывает этот метод
public void disconnect() {
if (mManager != null && mChannel != null) {
mManager.requestGroupInfo(mChannel, new WifiP2pManager.GroupInfoListener() {
@Override
public void onGroupInfoAvailable(WifiP2pGroup group) {
if (group != null && mManager != null && mChannel != null
&& group.isGroupOwner()) {
mManager.removeGroup(mChannel, new WifiP2pManager.ActionListener() {
@Override
public void onSuccess() {
Log.d("main", "removeGroup onSuccess -");
}
@Override
public void onFailure(int reason) {
Log.d("main", "removeGroup onFailure -" + reason);
}
});
}
}
});
}
}
Проблема возникает, когда пользователь затем пытается сыграть в другую игру с кем-то, отыскивая других игроков и затем соединяясь с ними. Когда они делают это после отсоединения от первого человека, с которым они соединялись, одноранговое соединение не работает.генерирует исключение из-за разорванного канала, и информация не может быть отправлена между двумя пользователями. Только после закрытия приложения, а затем его повторного открытия, пользователь ищет и подключается к кому-либо в первый раз с момента открытия приложения, чтоодноранговое соединение работает нормально. по существу, если я перезапуститьПо некоторым причинам, в приложении соединение работает нормально.Но должен быть менее тупой способ исправить основную проблему, и я не могу понять, что это такое.Я прочитал все предыдущие вопросы, связанные с ошибками прерванного канала, и все они говорят о том, что один конец закрывает соединение, в то время как другой все еще пытается записать их, но это не так, поскольку тогда было установлено предыдущее соединение.закончилась, и генерируется совершенно новый.Мне чего-то не хватает, что позволит мне решить эту проблему?
logcat:
I/art: After code cache collection, code=245KB, data=226KB
D/ViewRootImpl@33c15f0[MainActivity]: ViewPostImeInputStage processPointer 0
D/ViewRootImpl@33c15f0[MainActivity]: ViewPostImeInputStage processPointer 1
D/ViewRootImpl@33c15f0[MainActivity]: mHardwareRenderer.destroy()#4
dispatchDetachedFromWindow
D/InputTransport: Input channel destroyed: fd=90
D/ViewRootImpl@589584e[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 1
D/ViewRootImpl@589584e[MainActivity]: mHardwareRenderer.initializeIfNeeded()#2 mSurface={isValid=true -609390592}
V/InputMethodManager: Starting input:
tba=android.view.inputmethod.EditorInfo@c3f369e nm : com.example.hosse.myapplication ic=null
I/InputMethodManager: [IMM] startInputInner -
mService.startInputOrWindowGainedFocus
D/InputTransport: Input channel constructed: fd=91
Input channel destroyed: fd=94
E/ViewRootImpl: sendUserActionEvent() returned.
D/main: removeGroup onSuccess -
V/MainActivity: fivejava.net.SocketException: Software caused connection abort
D/AbsListView: in onLayout changed
D/ViewRootImpl@ca0894c[Toast]: ThreadedRenderer.create() translucent=true
D/InputTransport: Input channel constructed: fd=94
D/ViewRootImpl@ca0894c[Toast]: setView = android.widget.LinearLayout{6f7cd95 V.E...... ......I. 0,0-0,0} touchMode=true
D/ViewRootImpl@ca0894c[Toast]: dispatchAttachedToWindow
D/ViewRootImpl@ca0894c[Toast]: Relayout returned: oldFrame=[0,0][0,0] newFrame=[294,1596][786,1728] result=0x27 surface={isValid=true -593956864}
surfaceGenerationChanged=true
D/mali_winsys: EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000, [492x132]-format:1
D/ViewRootImpl@ca0894c[Toast]: mHardwareRenderer.initialize() mSurface={isValid=true -593956864} hwInitialized=true
D/ViewRootImpl@ca0894c[Toast]: MSG_RESIZED_REPORT: frame=Rect(294, 1596 - 786, 1728) ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
D/ViewRootImpl@ca0894c[Toast]: mHardwareRenderer.destroy()#4
D/ViewRootImpl@ca0894c[Toast]: dispatchDetachedFromWindow
D/InputTransport: Input channel destroyed: fd=94
D/ViewRootImpl@589584e[MainActivity]: ViewPostImeInputStage processPointer 0
D/ViewRootImpl@589584e[MainActivity]: ViewPostImeInputStage processPointer 1
I/art: Do partial code cache collection, code=249KB, data=240KB
I/art: After code cache collection, code=239KB, data=234KB
I/art: Increasing code cache capacity to 1024KB
D/AbsListView: in onLayout changed
D/ViewRootImpl@589584e[MainActivity]: ViewPostImeInputStage processPointer 0
D/ViewRootImpl@589584e[MainActivity]: ViewPostImeInputStage processPointer 1
D/AbsListView: onTouchUp() mTouchMode : 0
D/TextView: setTypeface with style : 0
D/TextView: setTypeface with style : 0
D/ViewRootImpl@c74834e[MainActivity]: ThreadedRenderer.create() translucent=true
D/InputTransport: Input channel constructed: fd=93
D/ViewRootImpl@c74834e[MainActivity]: setView = DecorView@30699d2[MainActivity] touchMode=true
I/Choreographer: Skipped 33 frames! The application may be doing too much work on its main thread.
D/ViewRootImpl@c74834e[MainActivity]: dispatchAttachedToWindow
D/ViewRootImpl@c74834e[MainActivity]: Relayout returned: oldFrame=[0,0][0,0] newFrame=[32,514][1047,1477] result=0x27 surface={isValid=true -593956864} surfaceGenerationChanged=true
D/mali_winsys: EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000, [1207x1155]-format:1
D/ViewRootImpl@c74834e[MainActivity]: mHardwareRenderer.initialize() mSurface={isValid=true -593956864} hwInitialized=true
D/ViewRootImpl@c74834e[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 1
D/ViewRootImpl@c74834e[MainActivity]: mHardwareRenderer.initializeIfNeeded()#2 mSurface={isValid=true -593956864}
V/InputMethodManager: Starting input: tba=android.view.inputmethod.EditorInfo@9f1dc6f nm : com.example.hosse.myapplication ic=null
I/InputMethodManager: [IMM] startInputInner - mService.startInputOrWindowGainedFocus
D/InputTransport: Input channel constructed: fd=90
Input channel destroyed: fd=91
I/Choreographer: Skipped 33 frames! The application may be doing too much work on its main thread.
D/ViewRootImpl@c74834e[MainActivity]: MSG_RESIZED_REPORT: frame=Rect(32, 514 - 1047, 1477) ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
D/ViewRootImpl@589584e[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 0
D/ViewRootImpl@c74834e[MainActivity]: ViewPostImeInputStage processPointer 0
D/ViewRootImpl@c74834e[MainActivity]: ViewPostImeInputStage processPointer 1
D/ViewRootImpl@c74834e[MainActivity]: mHardwareRenderer.destroy()#4
D/ViewRootImpl@c74834e[MainActivity]: dispatchDetachedFromWindow
D/InputTransport: Input channel destroyed: fd=93
D/ViewRootImpl@589584e[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 1
D/ViewRootImpl@589584e[MainActivity]: mHardwareRenderer.initializeIfNeeded()#2 mSurface={isValid=true -609390592}
V/InputMethodManager: Starting input: tba=android.view.inputmethod.EditorInfo@9fedd7c nm : com.example.hosse.myapplication ic=null
I/InputMethodManager: [IMM] startInputInner - mService.startInputOrWindowGainedFocus
D/InputTransport: Input channel constructed: fd=93
Input channel destroyed: fd=90
E/ViewRootImpl: sendUserActionEvent() returned.
D/ViewRootImpl@2e84605[Toast]: ThreadedRenderer.create() translucent=true
D/InputTransport: Input channel constructed: fd=91
D/ViewRootImpl@2e84605[Toast]: setView = android.widget.LinearLayout{f19865a V.E...... ......I. 0,0-0,0} touchMode=true
D/ViewRootImpl@2e84605[Toast]: dispatchAttachedToWindow
D/ViewRootImpl@2e84605[Toast]: Relayout returned: oldFrame=[0,0][0,0] newFrame=[310,1596][769,1728] result=0x27 surface={isValid=true -593956864} surfaceGenerationChanged=true
D/mali_winsys: EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000, [459x132]-format:1
D/ViewRootImpl@2e84605[Toast]: mHardwareRenderer.initialize() mSurface={isValid=true -593956864} hwInitialized=true
D/ViewRootImpl@2e84605[Toast]: MSG_RESIZED_REPORT: frame=Rect(310, 1596 - 769, 1728) ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
D/ViewRootImpl@2e84605[Toast]: mHardwareRenderer.destroy()#4
D/ViewRootImpl@2e84605[Toast]: dispatchDetachedFromWindow
D/InputTransport: Input channel destroyed: fd=91
V/MainActivity: threejava.net.BindException: Address already in use
D/TextView: setTypeface with style : 0
D/ViewRootImpl@7903a0a[MainActivity]: ThreadedRenderer.create() translucent=true
D/InputTransport: Input channel constructed: fd=91
D/ViewRootImpl@7903a0a[MainActivity]: setView = DecorView@94082e2[MainActivity] touchMode=true
V/MainActivity: sixjava.net.SocketException: Broken pipe
D/ViewRootImpl@7903a0a[MainActivity]: dispatchAttachedToWindow
D/ViewRootImpl@7903a0a[MainActivity]: Relayout returned: oldFrame=[0,0][0,0] newFrame=[32,253][1047,1738] result=0x27 surface={isValid=true -593956864} surfaceGenerationChanged=true
D/ViewRootImpl@7903a0a[MainActivity]: mHardwareRenderer.initialize() mSurface={isValid=true -593956864} hwInitialized=true
D/mali_winsys: EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000, [1207x1677]-format:1
D/ViewRootImpl@7903a0a[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 1
D/ViewRootImpl@7903a0a[MainActivity]: mHardwareRenderer.initializeIfNeeded()#2 mSurface={isValid=true -593956864}
V/InputMethodManager: Starting input: tba=android.view.inputmethod.EditorInfo@17e88f1 nm : com.example.hosse.myapplication ic=null
I/InputMethodManager: [IMM] startInputInner - mService.startInputOrWindowGainedFocus
D/InputTransport: Input channel constructed: fd=95
Input channel destroyed: fd=93
D/ViewRootImpl@7903a0a[MainActivity]: MSG_RESIZED_REPORT: frame=Rect(32, 253 - 1047, 1738) ci=Rect(0, 0 - 0, 0) vi=Rect(0, 0 - 0, 0) or=1
D/ViewRootImpl@589584e[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 0
V/MainActivity: sixjava.net.SocketException: Broken pipe