Your MyStreamSocket class does not need to extend Socket. The mysterious error message is because the Socket represented by MyStreamSocket is never connected to anything. The Socket referenced by its socket member is the one that is connected. Hence when you get the input stream from MyStreamSocket it genuinely is not connected. That causes an error, which means the client shuts down. That causes the socket to close, which the server duly reports
The use of BufferedReader is going to cause you problems. It always reads as much as it can into its buffer, so at the start of a file transfer it will read the "200" message and then the first few Kb of the file being sent which will get parsed as character data. The result will be a whole heap of bugs.
I suggest you get rid of BufferedReader right now and use DataInputStream and DataOutputStream instead. You can use the writeUTF and readUTF methods to send your textual commands. To send the file I would suggest a simple chunk encoding.
It's probably easiest if I give you code.
First your client class.
import java.io.*;
import java.net.InetAddress;
public class EchoClient2 {
public static void main(String[] args) {
InputStreamReader is = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(is);
File file = new File("C:\\MyFile.txt");
try {
System.out.println("Welcome to the Echo client.\n"
+ "What is the name of the server host?");
String hostName = br.readLine();
if( hostName.length() == 0 ) // if user did not enter a name
hostName = "localhost"; // use the default host name
System.out.println("What is the port number of the server host?");
String portNum = br.readLine();
if( portNum.length() == 0 ) portNum = "7"; // default port number
MyStreamSocket socket = new MyStreamSocket(
InetAddress.getByName(hostName), Integer.parseInt(portNum));
boolean done = false;
String echo;
while( !done ) {
System.out.println("Enter Code: 100 = Login, 200 = Upload, 400 = Logout: ");
String message = br.readLine();
boolean messageOK = false;
if( message.equals("100") ) {
messageOK = true;
System.out.println("Enter T-Number: (Use Uppercase 'T')");
String login = br.readLine();
if( login.charAt(0) == 'T' ) {
System.out.println("Login Worked fantastically");
} else {
System.out.println("Login Failed");
}
socket.sendMessage("100");
}
if( message.equals("200") ) {
messageOK = true;
socket.sendMessage("200");
socket.sendFile(file);
}
if( (message.trim()).equals("400") ) {
messageOK = true;
System.out.println("Logged Out");
done = true;
socket.sendMessage("400");
socket.close();
break;
}
if( ! messageOK ) {
System.out.println("Invalid input");
continue;
}
// get reply from server
echo = socket.receiveMessage();
System.out.println(echo);
} // end while
} // end try
catch (Exception ex) {
ex.printStackTrace();
} // end catch
} // end main
} // end class
Then your server class:
import java.io.*;
import java.net.*;
public class EchoServer2 {
static final String loginMessage = "Logged In";
static final String logoutMessage = "Logged Out";
public static void main(String[] args) {
int serverPort = 7; // default port
String message;
if( args.length == 1 ) serverPort = Integer.parseInt(args[0]);
try {
// instantiates a stream socket for accepting
// connections
ServerSocket myConnectionSocket = new ServerSocket(serverPort);
/**/System.out.println("Daytime server ready.");
while( true ) { // forever loop
// wait to accept a connection
/**/System.out.println("Waiting for a connection.");
MyStreamSocket myDataSocket = new MyStreamSocket(
myConnectionSocket.accept());
/**/System.out.println("connection accepted");
boolean done = false;
while( !done ) {
message = myDataSocket.receiveMessage();
/**/System.out.println("message received: " + message);
if( (message.trim()).equals("400") ) {
// Session over; close the data socket.
myDataSocket.sendMessage(logoutMessage);
myDataSocket.close();
done = true;
} // end if
if( (message.trim()).equals("100") ) {
// Login
/**/myDataSocket.sendMessage(loginMessage);
} // end if
if( (message.trim()).equals("200") ) {
File outFile = new File("C:\\OutFileServer.txt");
myDataSocket.receiveFile(outFile);
myDataSocket.sendMessage("File received "+outFile.length()+" bytes");
}
} // end while !done
} // end while forever
} // end try
catch (Exception ex) {
ex.printStackTrace();
}
} // end main
} // end class
Then the StreamSocket class:
public class MyStreamSocket {
private Socket socket;
private DataInputStream input;
private DataOutputStream output;
MyStreamSocket(InetAddress acceptorHost, int acceptorPort)
throws SocketException, IOException {
socket = new Socket(acceptorHost, acceptorPort);
setStreams();
}
MyStreamSocket(Socket socket) throws IOException {
this.socket = socket;
setStreams();
}
private void setStreams() throws IOException {
// get an input stream for reading from the data socket
input = new DataInputStream(socket.getInputStream());
output = new DataOutputStream(socket.getOutputStream());
}
public void sendMessage(String message) throws IOException {
output.writeUTF(message);
output.flush();
} // end sendMessage
public String receiveMessage() throws IOException {
String message = input.readUTF();
return message;
} // end receiveMessage
public void close() throws IOException {
socket.close();
}
public void sendFile(File file) throws IOException {
FileInputStream fileIn = new FileInputStream(file);
byte[] buf = new byte[Short.MAX_VALUE];
int bytesRead;
while( (bytesRead = fileIn.read(buf)) != -1 ) {
output.writeShort(bytesRead);
output.write(buf,0,bytesRead);
}
output.writeShort(-1);
fileIn.close();
}
public void receiveFile(File file) throws IOException {
FileOutputStream fileOut = new FileOutputStream(file);
byte[] buf = new byte[Short.MAX_VALUE];
int bytesSent;
while( (bytesSent = input.readShort()) != -1 ) {
input.readFully(buf,0,bytesSent);
fileOut.write(buf,0,bytesSent);
}
fileOut.close();
}
} // end class
Ditch the "helper" class. It is not helping you.