> I have a problem with a socket connection. I open a connection to the
> server, send some data and close it again. So far, so good. The problem
> arises when I want to send more data (eg. 50kbyte). In such a case, the
> Client always terminates with a SocketException and the message "broken
> pipe". The server is fine (or at least there is no exception).

Signature
[ don't email me support questions or followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
> > I have a problem with a socket connection. I open a connection to the
> > server, send some data and close it again. So far, so good. The problem
> > arises when I want to send more data (eg. 50kbyte). In such a case, the
> > Client always terminates with a SocketException and the message "broken
> > pipe". The server is fine (or at least there is no exception).
> If you closed the connection, then you need to open a new socket
> before you can send more data.
>
> If that's not the problem then you need to post your code.
This is not the problem.
I extracted the problematic code. The client is:
import java.net.*;
import java.io.*;
public class Client
{
public static void main(String[] args) {
byte[] sendData = new byte[1024];
byte[] rcvData = new byte[8];
try {
// connect to the node
Socket socket = new Socket("planetlab02.ethz.ch", 5452);
InputStream is = socket.getInputStream();
OutputStream os = socket.getOutputStream();
for(int i = 0; i < 50; i++) {
os.write(sendData);
os.flush();
System.out.print("written...");
is.read(rcvData);
System.out.println("read...");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
and the server:
import java.net.*;
import java.io.*;
public class Server {
public static void main(String[] args) {
try {
Socket socket = null;
InputStream is = null;
OutputStream os = null;
ServerSocket serverSocket = new ServerSocket(5452);
// accept connections until thread is terminated
while (true) {
socket = serverSocket.accept();
// if something tried to connect
is = socket.getInputStream();
os = socket.getOutputStream();
byte[] b = new byte[1024];
byte[] a = new byte[8];
for (int i = 0; i < 50; i++) {
is.read(b);
System.out.print("read...");
os.write(a);
os.flush();
System.out.println("written...");
}
socket.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
I know this code doesn't really make sense. But it's taken out of
context to illustrate the problem (which of course still exists). After
a few read/writes, the mentioned error occurs.
Thanks and regards,
Stefan Weber
Gordon Beaton - 21 Aug 2006 17:55 GMT
> I know this code doesn't really make sense. But it's taken out of
> context to illustrate the problem (which of course still exists).
> After a few read/writes, the mentioned error occurs.
The client will get the exception if the server stops reading and
closes the connection before the client has finished writing.
One problem in the code is that you incorrectly assume that each
read() reads the requested amount, which absolutely cannot be relied
on. Check the return value from read() and compensate for short reads.
Also, the read loop condition should be such that the server gives the
client a chance to close first. You can do that by reading to EOF, or
by determining from the contents of the sent data when the client has
finished writing.
/gordon

Signature
[ don't email me support questions or followups ]
g o r d o n + n e w s @ b a l d e r 1 3 . s e
Chris Uppal - 21 Aug 2006 18:05 GMT
> is.read(rcvData);
...
> is.read(b);
Try modifying your example so that you actually use the returned value from
these read() methods[*]. I suspect your client and server are getting out of
synch and the server is closing the socket before the client has written
everything it wants to.
-- chris
[*] And your real code too if it is written the same way -- it is /never/
correct to ignore the return value from read(); if you are doing so then your
code is already broken, and you may as well fix it before going on to look for
whatever other problems there may be.