JAVA writes a server and client that can upload files. The specific content is as follows
Server side
class Server { public static void main(String[] args) throws Exception { //Create the server Socket ServerSocket ss = new ServerSocket(10005); //Receive the client Socket fileLoaderSocket = ss.accept(); //Print the connection information String ip = fileLoaderSocket.getInetAddress().getHostAddress(); System.out.println(ip + "...connceected"); //Receive the file and save InputStream in = fileLoaderSocket.getInputStream(); //Instantiate the object fileSave OutputStream fileSave = new FileOutputStream("E://3.mp3"); //Create an array buf byte[] buf = new byte[1024]; int len = 0; //Defend whether the end of the file is read while((len=in.read(buf)) != -1) { fileSave.write(buf, 0, len); //Refresh fileSave.flush(); } //Return file copying information BufferedWriter out = new BufferedWriter(new OutputStreamWriter(fileLoaderSocket.getOutputStream())); out.write("File upload successful"); //Refresh out.flush(); //Resource close ss.close(); fileLoaderSocket.close(); fileSave.close(); } }Client:
class Client{ public static void main(String[] args) throws Exception { //Create Socket service Socket fileLoaderSocket = new Socket("168.168.168.94", 10005); //Read the file locally from the client and write to the socket's output stream OutputStream out = fileLoaderSocket.getOutputStream(); //Instantiate the object fileReader InputStream fileRead = new FileInputStream("G://2.mp3"); //Create an array byte[] buf = new byte[1024]; int len = 0; //Judge whether the end of the file is read while((len=fileRead.read(buf)) != -1) { out.write(buf, 0, len); } //Tell the server that the file has been transferred fileLoaderSocket.shutdownOutput(); //Get the information feedback from the server BufferedReader in = new BufferedReader(new InputStreamReader(fileLoaderSocket.getInputStream())); String serverBack = in.readLine(); System.out.println(serverBack); //Resource close fileLoaderSocket.close(); fileRead.close(); } }The following program is copied directly from elsewhere for learning reference:
Java Socket Programming
For Java Socket programming, there are two concepts, one is ServerSocket and the other is Socket. The server and the client are connected through Socket, and then they can communicate. First, ServerSocket will listen to a port on the server. When it is found that the client has a Socket to try to connect to it, it will accept the connection request of the Socket, and at the same time establish a corresponding Socket on the server to communicate with it. In this way, there are two sockets, one on the client and one on the server.
Communication between Sockets is actually very simple. When the server writes something into the Socket output stream, the client can read the corresponding content through the Socket input stream. The Socket and Socket are connected in two directions, so the client can also write things into the corresponding Socket output stream, and then the corresponding Socket input stream of the server can read out the corresponding content. Here are some examples of server-side communication with clients:
1. Client write and server read
Server Java code
public class Server { public static void main(String args[]) throws IOException { //For simplicity, all exception information is thrown out int port = 8899; //Define a ServerSocket listening on port 8899 ServerSocket server = new ServerSocket(port); //The server tries to receive connection requests from other Sockets. The server's accept method is a blocking Socket socket = server.accept(); //After establishing a connection with the client, we can obtain the socket's InputStream and read the information sent by the client. Reader reader = new InputStreamReader(socket.getInputStream()); char chars[] = new char[64]; int len; StringBuilder sb = new StringBuilder(); while ((len=reader.read(chars)) != -1) { sb.append(new String(chars, 0, len)); } System.out.println("from client: " + sb); reader.close(); socket.close(); server.close(); } }The operation of the server to read data from the Socket's InputStream is also blocking. If the data is not read from the input stream, the program will remain there until the client writes data into the Socket's output stream or closes the Socket's output stream. Of course, the same is true for client sockets. After the operation is completed, remember to close the corresponding resources before the entire program is finished, that is, close the corresponding IO stream and socket.
Client Java code
public class Client { public static void main(String args[]) throws Exception { //For simplicity, all exceptions are thrown out directly String host = "127.0.0.1"; //The IP address of the server to be connected is int port = 8899; //The corresponding listening port of the server to be connected//The connection is established with the server Socket client = new Socket(host, port); //After establishing the connection, you can write data to the server Writer writer = new OutputStreamWriter(client.getOutputStream()); writer.write("Hello Server."); writer.flush();//Remember flush writer.close(); client.close(); } }When writing data to the Socket output stream, you should pay attention to one thing. If the program does not correspond to the shutdown of the output stream after the write operation, but performs other blocking operations (such as reading data from the input stream), remember to flush it. Only in this way can the server receive the data sent by the client, otherwise it may cause unlimited waiting for each other. This issue will be mentioned later when talking about the client and server reading and writing at the same time.
2. The client and the server read and write at the same time
As mentioned earlier, Sockets communicate in two-way ways, which can both receive data and send data.
Server Java code
public class Server { public static void main(String args[]) throws IOException { //For simplicity, all exception information is thrown out int port = 8899; //Define a ServerSocket listening on port 8899 ServerSocket server = new ServerSocket(port); //The server tries to receive connection requests from other Sockets. The server's accept method is a blocking Socket socket = server.accept(); //After establishing a connection with the client, we can obtain the socket's InputStream and read the information sent by the client. Reader reader = new InputStreamReader(socket.getInputStream()); char chars[] = new char[64]; int len; StringBuilder sb = new StringBuilder(); while ((len=reader.read(chars)) != -1) { sb.append(new String(chars, 0, len)); } System.out.println("from client: " + sb); //Write a sentence after reading it Writer writer = new OutputStreamWriter(socket.getOutputStream()); writer.write("Hello Client."); writer.flush(); writer.close(); reader.close(); socket.close(); server.close(); } }In the above code, we first read the data sent by the client from the input stream, and then write the data into the output stream to the client, and then close the corresponding resource file. In fact, the above code may not run in the way we assumed in advance, because reading data from the input stream is a blocking operation. When data is read in the above while loop, the loop body will be executed, otherwise it will be blocked, so that the subsequent write operations will never be executed. The while loop will stop unless the corresponding Socket of the client is closed and blocked. The solution to this situation where it may never be executed is that the while loop needs to be conditionally jumped out. Looking at the above code, the only thing that changes is the length len and the data that is read. len is no longer usable, and the only thing that can be used is the data that is read. In this case, we usually agree on an end tag. When the data sent by the client contains a certain end tag, it means that the current data has been sent, and at this time we can loop out. Then the improved code will look like this:
Java code
public class Server { public static void main(String args[]) throws IOException { //For simplicity, all exception information is thrown out int port = 8899; //Define a ServerSocket listening on port 8899 ServerSocket server = new ServerSocket(port); //The server tries to receive connection requests from other Sockets. The server's accept method is a blocking Socket socket = server.accept(); //After establishing a connection with the client, we can obtain the socket's InputStream and read the information sent by the client. Reader reader = new InputStreamReader(socket.getInputStream()); char chars[] = new char[64]; int len; StringBuilder sb = new StringBuilder(); String temp; int index; while ((len=reader.read(chars)) != -1) { temp = new String(chars, 0, len); if ((index = temp.indexOf("eof")) != -1) {//The reception is ended when eof is encountered sb.append(temp.substring(0, index)); break; } sb.append(temp); } System.out.println("from client: " + sb); //Write a sentence after reading Writer writer = new OutputStreamWriter(socket.getOutputStream()); writer.write("Hello Client."); writer.flush(); writer.close(); reader.close(); socket.close(); server.close(); } }In the above code, when the server reads the end mark sent by the client, that is, "eof", the data reception will be terminated and the loop will be terminated, so that the subsequent code can continue.
Client Java code
public class Client { public static void main(String args[]) throws Exception { //For simplicity, all exceptions are thrown out directly String host = "127.0.0.1"; //The IP address of the server to be connected int port = 8899; //The corresponding listening port of the server to be connected//The connection is established with the server Socket client = new Socket(host, port); //After establishing the connection, you can write data to the server Writer writer = new OutputStreamWriter(client.getOutputStream()); writer.write("Hello Server."); writer.flush(); //Read after writing Reader reader = new InputStreamReader(client.getInputStream()); char chars[] = new char[64]; int len; StringBuffer sb = new StringBuffer(); while ((len=reader.read(chars)) != -1) { sb.append(new String(chars, 0, len)); } System.out.println("from server: " + sb); writer.close(); reader.close(); client.close(); } }In the above code, we first sent a piece of data to the server, and then read the data returned by the server. Like the previous server, it may cause the program to hang there all the time and never jump out of the while loop. This code is combined with the first code of the server, just let us analyze that the server will always receive data there, and will never jump out of the while loop, so there will be no subsequent server to return data to the client, and the client will not be able to receive data returned by the server. The solution is shown in the second code of the server. After the client sends the data, write an end mark into the output stream to tell the server that the data has been sent. The server also sends a mark to tell the client after the data is returned. Then the modified client code should look like this:
Java code
public class Client { public static void main(String args[]) throws Exception { //For simplicity, all exceptions are thrown out directly String host = "127.0.0.1"; //The IP address of the server to be connected is int port = 8899; //The corresponding listening port of the server to be connected//The connection is established with the server Socket client = new Socket(host, port); //After establishing the connection, you can write data to the server Writer writer = new OutputStreamWriter(client.getOutputStream()); writer.write("Hello Server."); writer.write("eof"); writer.flush(); //Read after writing Reader reader = new InputStreamReader(client.getInputStream()); char chars[] = new char[64]; int len; StringBuffer sb = new StringBuffer(); String temp; int index; while ((len=reader.read(chars)) != -1) { temp = new String(chars, 0, len); if ((index = temp.indexOf("eof")) != -1) { sb.append(temp.substring(0, index)); break; } sb.append(new String(chars, 0, len)); } System.out.println("from server: " + sb); writer.close(); reader.close(); client.close(); } }The most common form we use in daily life is that the client sends data to the server, and the server receives the data and returns the corresponding results to the client. However, there is no longer such a one-to-one relationship between the client and the server, but the situation where multiple clients correspond to the same server as mentioned below.
3. Multiple clients connect to the same server
For the two examples mentioned above, the server ends after receiving a client's request and cannot receive requests from other clients, which often cannot meet our requirements. Usually we do this:
Java code
public class Server { public static void main(String args[]) throws IOException { //For simplicity, all exception information is thrown out int port = 8899; //Define a ServerSocket listening on port 8899 ServerSocket server = new ServerSocket(port); while (true) { //The server tries to receive connection requests from other Sockets. The server's accept method is a blocking Socket socket = server.accept(); //After establishing a connection with the client, we can obtain the socket's InputStream and read the information sent by the client. Reader reader = new InputStreamReader(socket.getInputStream()); char chars[] = new char[64]; int len; StringBuilder sb = new StringBuilder(); String temp; int index; while ((len=reader.read(chars)) != -1) { temp = new String(chars, 0, len); if ((index = temp.indexOf("eof")) != -1) {//The reception is ended when eof is encountered sb.append(temp.substring(0, index)); break; } sb.append(temp); } System.out.println("from client: " + sb); //Write a sentence after reading Writer writer = new OutputStreamWriter(socket.getOutputStream()); writer.write("Hello Client."); writer.flush(); writer.close(); reader.close(); socket.close(); } } } In the above code, we used a dead loop, where the ServerSocket calls its accept method to try to receive a connection request from the client. When the request is not received, the program will block here until it receives the connection request from the client, and then communicate with the client that has established the connection. After that, it will then execute the loop body and try to receive a new connection request again. This way our ServerSocket can receive connection requests from all clients and communicate with them. This implements a simple mode of communication with multiple clients on one server.
In the above example, although one server is implemented to communicate with multiple clients, there is still a problem. In the above example, our server handles the client's connection request synchronously. Every time we receive a connection request from the client, we must first communicate with the current client before we can process the next connection request. This will seriously affect the performance of the program when there are more concurrency. For this reason, we can change it to the following asynchronous processing of communication with the client:
Java code
public class Server { public static void main(String args[]) throws IOException { //For simplicity, all exception information is thrown out int port = 8899; //Define a ServerSocket listening on port 8899 ServerSocket server = new ServerSocket(port); while (true) { //The server tries to receive connection requests from other Sockets. The server's accept method is a blocking Socket socket = server.accept(); //Every time a Socket is received, a new thread is established to handle it new Thread(new Task(socket)).start(); } } /** * */ static class Task implements Runnable { private Socket socket; public Task(Socket socket) { this.socket = socket; } public void run() { try { handleSocket(); } catch (Exception e) { e.printStackTrace(); } } /** * Communicate with client Socket* @throws Exception */ private void handleSocket() throws Exception { Reader reader = new InputStreamReader(socket.getInputStream()); char chars[] = new char[64]; int len; StringBuilder sb = new StringBuilder(); String temp; int index; while ((len=reader.read(chars)) != -1) { temp = new String(chars, 0, len); if ((index = temp.indexOf("eof")) != -1) {//The reception is ended when eof is encountered sb.append(temp.substring(0, index)); break; } sb.append(temp); } System.out.println("from client: " + sb); //Write a sentence after reading Writer writer = new OutputStreamWriter(socket.getOutputStream()); writer.write("Hello Client."); writer.flush(); writer.close(); reader.close(); socket.close(); } } } In the above code, every time the ServerSocket receives a new Socket connection request, a new thread will be generated to communicate with the current Socket, which will achieve the asynchronous processing of communication with the client Socket.
When receiving data from Socket's InputStream, reading a little bit like the above is too complicated. Sometimes we will use BufferedReader to read one line at a time, such as:
Java code
public class Server { public static void main(String args[]) throws IOException { //For simplicity, all exception information is thrown out int port = 8899; //Define a ServerSocket listening on port 8899 ServerSocket server = new ServerSocket(port); while (true) { //The server tries to receive connection requests from other Sockets. The server's accept method is a blocking Socket socket = server.accept(); //Every time a Socket is received, a new thread is established to handle it new Thread(new Task(socket)).start(); } } /** * */ static class Task implements Runnable { private Socket socket; public Task(Socket socket) { this.socket = socket; } public void run() { try { handleSocket(); } catch (Exception e) { e.printStackTrace(); } } /** * Communicate with client Socket* @throws Exception */ private void handleSocket() throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); StringBuilder sb = new StringBuilder(); String temp; int index; while ((temp=br.readLine()) != null) { System.out.println(temp); if ((index = temp.indexOf("eof")) != -1) {//End the reception when eof is encountered sb.append(temp.substring(0, index)); break; } sb.append(temp); } System.out.println("from client: " + sb); //Write a sentence after reading Writer writer = new OutputStreamWriter(socket.getOutputStream()); writer.write("Hello Client."); writer.write("eof/n"); writer.flush(); writer.close(); br.close(); socket.close(); } } }At this time, it should be noted that the readLine method of BufferedReader reads one line at a time. This method is blocked. The program will not continue to execute until it reads one line of data. So when will readLine read a line? The readLine method will not think that it has been read a line until the program encounters a newline or the ending character of the corresponding stream. It will end its blockage and let the program continue to execute. Therefore, when we use the BufferedReader's readLine to read data, we must remember to write line breaks in the corresponding output stream (it will be automatically marked as end after the stream ends, and readLine can be recognized). After writing the line breaks, we must remember to flush if the output stream is not closed immediately, so that the data will be truly written from the buffer. Corresponding to the above code, our client program should be written like this:
Java code
public class Client { public static void main(String args[]) throws Exception { //For simplicity, all exceptions are thrown out directly String host = "127.0.0.1"; //The IP address of the server to be connected is int port = 8899; //The corresponding listening port of the server to be connected//The connection is established with the server Socket client = new Socket(host, port); //After establishing the connection, you can write data to the server Writer writer = new OutputStreamWriter(client.getOutputStream()); writer.write("Hello Server."); writer.write("eof/n"); writer.flush(); //Read after writing BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream())); StringBuffer sb = new StringBuffer(); String temp; int index; while ((temp=br.readLine()) != null) { if ((index = temp.indexOf("eof")) != -1) { sb.append(temp.substring(0, index)); break; } sb.append(temp); } System.out.println("from server: " + sb); writer.close(); br.close(); client.close(); } }4. Set the timeout time
Suppose there is such a requirement that our client needs to obtain XX information from the server through Socket and then display it to the user on the page. We know that Socket is blocking when reading data, and if you don't read the data, the program will keep blocking there. When synchronizing the request, we must not allow such a situation to happen. This requires us to control the blocking interrupt after the request reaches a certain time so that the program can continue to run. Socket provides us with a setSoTimeout() method to set the timeout time of the received data in milliseconds. When the set timeout time is greater than 0 and after this time the Socket has not received the returned data, the Socket will throw a SocketTimeoutException.
Suppose we need to control our client to interrupt and block before reading the data for 10 seconds after starting to read the data, we can do this:
Java code
public class Client { public static void main(String args[]) throws Exception { //For simplicity, all exceptions are thrown out directly String host = "127.0.0.1"; //The IP address of the server to be connected is int port = 8899; //The corresponding listening port of the server to be connected//The connection is established with the server Socket client = new Socket(host, port); //After establishing the connection, you can write data to the server Writer writer = new OutputStreamWriter(client.getOutputStream()); writer.write("Hello Server."); writer.write("eof/n"); writer.flush(); //Read after writing BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream())); //Set the timeout to 10 seconds client.setSoTimeout(10*1000); StringBuffer sb = new StringBuffer(); String temp; int index; try { while ((temp=br.readLine()) != null) { if ((index = temp.indexOf("eof")) != -1) { sb.append(temp.substring(0, index)); break; } sb.append(temp); } } catch (SocketTimeoutException e) { System.out.println("Data read timeout."); } System.out.println("from server: " + sb); writer.close(); br.close(); client.close(); } }5. Receive data garbled code
For such cases when the server or client receives garbled Chinese code, it is usually because the encoding used when the data is sent is inconsistent with the encoding used when the data is received. For example, there is a server code like this:
Java code
public class Server { public static void main(String args[]) throws IOException { //For simplicity, all exception information is thrown out int port = 8899; //Define a ServerSocket listening on port 8899 ServerSocket server = new ServerSocket(port); while (true) { //The server tries to receive connection requests from other Sockets. The server's accept method is a blocking Socket socket = server.accept(); //Every time a Socket is received, a new thread is established to handle it new Thread(new Task(socket)).start(); } } /** * */ static class Task implements Runnable { private Socket socket; public Task(Socket socket) { this.socket = socket; } public void run() { try { handleSocket(); } catch (Exception e) { e.printStackTrace(); } } /** * Communicate with client Socket* @throws Exception */ private void handleSocket() throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK")); StringBuilder sb = new StringBuilder(); String temp; int index; while ((temp=br.readLine()) != null) { System.out.println(temp); if ((index = temp.indexOf("eof")) != -1) {//End reception when eof is encountered sb.append(temp.substring(0, index)); break; } sb.append(temp); } System.out.println("Client: " + sb); //Write a sentence after reading Writer writer = new OutputStreamWriter(socket.getOutputStream(), "UTF-8"); writer.write("Hello, client."); writer.write("eof/n"); writer.flush(); writer.close(); br.close(); socket.close(); } } }I'm a little confused when I used it here for testing. In the above server code, we clearly define the use of GBK encoding to read data when defining the input stream, and clearly specify that the use of UTF-8 encoding to send data when defining the output stream. If the client does not send data in GBK encoding when sending data on the client, the data received by the server is likely to be garbled; similarly, if the client does not send data encoding when sending data on the server, that is, UTF-8 encoding to receive data, it is also very likely that data garbled will occur. Therefore, for the above server code, in order to enable our program to read the data sent by the other party without garbled code, our client should be like this:
Java code
public class Client { public static void main(String args[]) throws Exception { //For simplicity, all exceptions are thrown out directly String host = "127.0.0.1"; //The IP address of the server to be connected int port = 8899; //The corresponding listening port of the server to be connected//The connection is established with the server Socket client = new Socket(host, port); //After establishing the connection, you can write data to the server Writer writer = new OutputStreamWriter(client.getOutputStream(), "GBK"); writer.write("Hello, server."); writer.write("eof/n"); writer.flush(); //Read after writing BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream(), "UTF-8")); //Set the timeout to 10 seconds client.setSoTimeout(10*1000); StringBuffer sb = new StringBuffer(); String temp; int index; try { while ((temp=br.readLine()) != null) { if ((index = temp.indexOf("eof")) != -1) { sb.append(temp.substring(0, index)); break; } sb.append(temp); } } catch (SocketTimeoutException e) { System.out.println("Data read timeout."); } System.out.println("Server: " + sb); writer.close(); br.close(); client.close(); } }This article has been compiled into "Summary of Java Upload Operation Techniques", and everyone is welcome to learn and read.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.