MyStreamSocket
クラスで Socket を拡張する必要はありません。不思議なエラー メッセージは、MyStreamSocket によって表される Socket が何にも接続されていないために発生します。そのsocket
メンバーによって参照される Socket は、接続されているものです。したがって、MyStreamSocket から入力ストリームを取得すると、実際には接続されません。これは、クライアントがシャットダウンすることを意味するエラーを引き起こします。これにより、ソケットが閉じられ、サーバーが正式に報告します
BufferedReader を使用すると問題が発生します。常に可能な限り多くをバッファーに読み込むため、ファイル転送の開始時に「200」メッセージを読み取り、次に送信されるファイルの最初の数キロバイトを読み取り、文字データとして解析します。その結果、大量のバグが発生します。
今すぐ BufferedReader を取り除き、代わりに DataInputStream と DataOutputStream を使用することをお勧めします。writeUTF および readUTF メソッドを使用して、テキスト コマンドを送信できます。ファイルを送信するには、単純なチャンク エンコーディングをお勧めします。
コードを提供すると、おそらく最も簡単です。
まず、クライアント クラス。
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
次に、サーバークラス:
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
次に、StreamSocket クラス:
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
「ヘルパー」クラスを捨てます。それはあなたを助けていません。