In my application I have two people on different devices connect through wifi direct peer to peer connection. When they are connected, one user is assigned host" and the other "client".
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();
}
}
};
The host runs the ServerClass , while the client runs the ClientClass. Both of them use the SendRecieve class to send each other data, which is received through a handler. This all works fine
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);
}
}
}
and then when the game is ended the players disconnect by pressing a button that calls this method
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);
}
});
}
}
});
}
}
A problem arises When the user then tries to play another game with someone by looking for other players and then connecting with them. When they do this after disconnecting from the first person they connected with, the peer to peer connection doesn't work. It throws a broken pipe exception and information is not able to be sent between the two users. It is not until the app is closed then opened again, then the user searches for and connects to someone for the first time since the app was opened that the peer to peer connection works normally. essentially if I restart the app the connection seems to work fine, for some reason. But there must be a less blunt way of fixing the underlying issue, and I can't seem to figure out what it is. I've read all previous questions having to do with broken pipe errors and they all talk about one end closing the connection while the other is still trying to write to them, but that isn't the case here since the previous connection is made then ended, and a entirely new one is generated. Is there something I'm missing that will allow me to solve this issue?
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