除了那些我在網上搜集的造成的因素,例如一端關閉,另一端沒關閉;資料正發送時Server關閉,而Client無法從輸入資料流中讀取,還有什麼資料庫的服務,還有什麼IIS的服務需要關閉。
個人的理解,如果按照規範或者書上例子編寫,錯誤可能有如下,雖然根本原因和上述是相同的,但具體的導致原因可能不同。
用戶端,發送資料時的結束符,一般以“\n”結束,如果忘記使用可能會產生該錯誤,或者一直等待,對於本地的伺服器,自己編寫的,加一個就可以了,但是如果對網路上的伺服器,必須加兩個。
連接埠的佔用,比如你正在開著瀏覽器,結果編程式使用80連接埠,必然會導致此錯誤的產生。
伺服器或者用戶端的檔案目錄,當讀寫時,找不到正確的目錄,並非一定會告訴你是IO錯誤,而可能反映是Socket錯誤,所以這個也要務必檢查。
關於在用戶端和伺服器,socket關閉,最容易產生此類錯誤,關閉的時機不對,就會出錯,不關閉也會出錯,例如,伺服器端不關閉socket,伺服器端不會報錯,但是對於用戶端來說,如果用infromstream讀取,當資料發送完畢時,再次readline,便會出錯,正常情況下,在伺服器端關閉socket,此時用戶端的讀取會讀取到null,而不會產生錯誤。
就是這樣的。
import java.io.*;
import java.util.*;
import java.net.*;
public class WebServer {
// the work content of the Server
final static String path = "F:\\work\\SSD8\\EX1-lab";
//the edition of the HTTP
final static String ipEdition = "HTTP/1.1";
//the communication port of the Server
final static int port = 80;
//main method to respond for a client
public static void main(String argv[]){
try{
System.out.println("The Server start!\n");
ServerSocket listenSocket = new ServerSocket(port);
while(true){
Socket connectionSocket = listenSocket.accept();
respondToClient(connectionSocket);
}
}catch(SocketException e){
System.out.println("socket error in Server\n" + e.getMessage());
}catch(IOException e){
System.out.println("io error in Server\n" + e.getMessage());
}
}
// method to respond cient, including to receice and send the data
public static void respondToClient(Socket connectionSocket) throws IOException,SocketException
{
String requestMessagegetline;
String filename;
BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());
requestMessagegetline = inFromClient.readLine();
StringTokenizer token = new StringTokenizer(requestMessagegetline," ");
if(token.nextToken().equals("GET")){
filename = path + token.nextToken();
File file = new File(filename);
if(file.exists()){
if(ipEdition.equals(token.nextToken())){
int numOfBytes = (int)file.length();
FileInputStream inFile = new FileInputStream(filename);
byte[] fileInBytes = new byte[numOfBytes];
inFile.read(fileInBytes);
System.out.println("ready send the head\n");
outToClient.writeBytes("HTTP/1.0 200 Document Follow\r\n");
if(filename.endsWith("html"))
outToClient.writeBytes("Content-Type: text/html\r");
if(filename.endsWith(".gif"))
outToClient.writeBytes("Content-Type: image/gif\r");
if(filename.endsWith(".jpg"))
outToClient.writeBytes("Content-Type: image/jpeg\r");
outToClient.writeBytes("Content-length: " + numOfBytes + "\r\n");
outToClient.writeBytes("\r\n");
System.out.println("finish send the head\n");
System.out.println("ready send the filedata\n");
outToClient.write(fileInBytes,0,numOfBytes);
System.out.println("finish the data send\n");
}else{
outToClient.writeBytes("HTTP/1.0 505 Version Not Supported\r\n");
}
}else{
outToClient.writeBytes("HTTP/1.0 404 Not Found\r\n");
}
}else{
outToClient.writeBytes("HTTP/1.0 400 Bad Request\r\n");
}
System.out.println("closed\n");
connectionSocket.close();
}
}
import java.io.*;
import java.net.*;
import java.util.*;
//content:EX1,The client to send message to server to get the head and the data
public class TCPClient {
// the communication port number
final static int portNumber = 5678;
final String pathOfFile = "F:\\work\\SSD8\\EX1-lab\\";
// the data packet of the head from the Server
public String packetHead;
//the data in the packet of the entity
public String fileData;
// name of the Server
public String serverName;
//The IP proticol edition of the user's
public String ipEdition;
//main method to run the program
public static void main(String argv[]){
TCPClient client = new TCPClient();
String userRequest = null;
if(argv[0] != null)client.serverName = argv[0];
else return;
try{
System.out.println("Enter the request for the Server:");
BufferedReader inFromUser = new BufferedReader(
new InputStreamReader(System.in));
userRequest = inFromUser.readLine();
if(client.connectToServer(userRequest))
client.writeToFile();
System.out.println("Finish");
}catch(SocketException e){
System.out.println("socket error in Client!" + e.getMessage());
}catch(IOException e){
System.out.println("io exception in Client!" + e.getMessage());
}
}
//initialize the data of Client
public TCPClient(){
packetHead = "";
fileData = "";
serverName = null;
ipEdition = null;
}
// write the data from the Sever to a specific file
public void writeToFile()throws IOException{
System.out.println("Enter the filename you want to save:");
BufferedReader inFromUser = new BufferedReader(
new InputStreamReader(System.in));
File file = new File(pathOfFile + inFromUser.readLine());
FileWriter fileWrites = new FileWriter(file);
fileWrites.write(fileData);
fileWrites.close();
}
//create Socket to the Server and send it the request by user
// it will get a data packet, separate the data and initialize some valubal of the Client
public boolean connectToServer(String requestForServer)throws IOException{
Socket clientSocket = new Socket(serverName,portNumber);
if(clientSocket.isConnected()){
DataOutputStream outToServer = new DataOutputStream(
clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
outToServer.writeBytes(requestForServer + "\r\n" + "\r\n");
System.out.println("connect!");
System.out.println("From Server :");
String S = inFromServer.readLine();
while(S != null && !S.startsWith("<") ){
packetHead += S + "\r";
S = inFromServer.readLine();
}
System.out.println(packetHead);
StringTokenizer token = new StringTokenizer(packetHead," ");
token.nextToken();
String conditionKey = token.nextToken();
if(conditionKey.equals("200"))
{
while(S != null){
System.out.println(S);
fileData += S;
S = inFromServer.readLine();
}
return true;
}
System.out.println("client is closed\n");
clientSocket.close();
}
return false;
}
}