Saturday, January 21, 2003 After the actual concept was established through the procedure, it should now return to the most beginning, what is Socket? It is a way to implement computer communications, this is undoubted. But how can be easier What is the principle of understanding the language comparative image and not to describe its principles?
Bruce Eckel describes the socket in his "Java Programming Thought" book: socket is a software abstraction that expresses the connection "terminal" between the two machines. For a given connection, there is a socket on each machine, you can also imagine that there is a virtual "cable", "cable", "cable", inserted into the socket. Of course, physical hardware and cable connections between machines are completely unknown. Abstract full purpose is to make us do not need to know the details that you don't have to know.
According to my understanding, the abstract point, a socket is a telephone handset, you have one, there is a person with your call, just one of the people's handset called Serversocket, another person's earpiece called Socket. As for who is ServerSocket, who is socket, this is not important, because the client and server are relatively relative, can be transformed with each other. Two people of the call have established a channel by picking up two receivers. This channel is not connected. It is not that both sides pick up the handset. If only one party picks up the handset, then I can only hear some doodle sounds, and the channel is different. Here, the process of picking up the handset is the process of Socket initialization. After establishing the channel, Just after everyone picking up the handset, the people at both ends can start talking. There are two processes here, namely A. B is listening to B, and B is talking to A, A listening, these two processes are through two The line is completed. Transmission on these two lines is the stream. The stream hides all the details of all transmission, so that both communications believe that they pass the sound instead of the code.
The program of the server-side written server is actually a single task version, the server's processing mechanism to the client can only process one connection in the same time period, because the HandleConnection takes a constant looping block method, detects one, handle it One, then then detect one, then process one, if there are multiple connections to request, it can only queue waiting. This program cannot be paid to multiple connections in the network, because you can't guarantee only A customer proposes a connection request with the server, and uses a blocking method to deal with multiple customers to connect their speed.
This gives birth to a multi-connection version. Obviously, our requirements can be achieved by multithreading.
Since we want to resolve the problem of dealing with the customer connection, our work is just a modification of the server side. It is not difficult to launch, which is not difficult to launch, and immediately build a thread to handle it, then continue to listen Next connection request. So, we only need to put the code in the handleConnection to the thread in executation code, and add the code to the new thread in the HandleConnection, it is very simple.
Like the same style, let's observe the code details of each part. First, create a class MultithreadRemoteFileServer for this multi-thread version.
Take a look at the definition of this class import java.io. *; Import java.net. *;
public class MultiThreadRemoteFileServer {protected int listenPort; public MultiThreadRemoteFileServer (int aListenPort) {} public static void main (String [] args) {} public void acceptConnections () {} public void handleConnection (Socket incomingConnection) {}}
Almost with RemoteFileServer, the only difference is to add a constructor in this class we created now, which is to make the monitored port number from us. Definitions
Public MultithreadedRemoteFileServer (Int alistenport) {listenport = alistenport;
First look main () public static void main (String [] args) {MultithreadedRemoteFileServer server = new MultithreadedRemoteFileServer (3000); server.acceptConnections ();} indistinguishable from it, and RemoteFileServer the main () function, but the port number created The main program is specified.
The changes we mainly care have to see the AcceptConnection listener public void acceptconnections () {Try {ServerSocket Server = New Serversocket (Listenport, 5); // Notes not, more parameters when establishing server sockets, this parameter It is used to designate the maximum number of applications to apply to connect, the default is 50 socket incomingconnection = null; while (true) {incomingconnection = server.accept (); handleconnection (incomingconnection);}} catch (bindexception e) {system. Out.println ("Unable to bind to port" listenport);} catch (ioException e) {system.out.println ("Unable to instantiate a serversocket on port:" listenport);}}
The changed place will be one, more parameters. Here is its working mechanism. Suppose we specify the number of days (Backlog Values) is 5 and five client requests to connect to our server. Our server will start to handle the first connection, but it takes a long time to process the connection. Since our pending value is 5, we can put five requests in the queue once. We are dealing with one, so this means that there are other five waiting. Waiting and being processed in a total of six. When our server is still busy accepting one connection (remember 2-6 in the queue), if there is a seventh client to apply for an application, then the seventh client will be rejected.
Next, our next change is obviously in the method of handling the monitored thread. In the previous, in the multi-threaded version, we detect a connection request, then generate a thread immediately, then do not use It's, then here is a new sentence of new threads.
Public Void HandleConnection (socket connectiontohandle) {new connectionHandler (connectiontohandle). start ();}
We note that there is a new CONNECTIONHANDLER. This class is runnable, that is, an interface class (this is a thread that is implemented with the interface. If you don't understand, you can take a look at the thread on the thread on the 17th. We created a new THREAD with ConnectionHandler and launch it. As we have said, the code in the HandleConnection in RemoteFileServer is transferred to the RUN () method of this interface CONNECTIONHANDLER.
Then let's take a look at the definition of the entire ConnectionHandler class.
class ConnectionHandler implements Runnable {protected Socket socketToHandle; public ConnectionHandler (Socket aSocketToHandle) {socketToHandle = aSocketToHandle; Socket // the constructor, to be treated as a parameter example come} public void run () {// read the original on the Socket / write code here try {PrintWriter streamWriter = new PrintWriter (socketToHandle.getOutputStream ()); BufferedReader streamReader = new BufferedReader (new InputStreamReader (socketToHandle.getInputStream ())); String fileToRead = streamReader.readLine (); BufferedReader FileReader = New BufferedReader (New FileRead (Filetoread);
String line = null; while ((line = fileReader.readline ())! = Null) streamwriter.println (line);
FileReader.close (); streamwriter.close (); streamReader.close ();} catch (exception e) {system.out.println ("Error Handling a client: e);}}}
What is done by the Run () method of ConnectionHandler is what is done by HandleConnection () on RemoteFileServer. First pack the InputStream and OutputStream (with Socket GetputStream () and GetInputStream ()) to BufferedReader and PrintWriter. Then we use these code to read the target file line by line. Since the file path is installed in InputStream, the FileReader stream will need to be packaged in the middle, and then read through the bufferedReader package.
Our multi-threaded server is completed. Similarly, we review the steps to create and use "multi-threaded" server:
1. Modify AcceptConnections () to instantiate Serversocket with default 50 (or any specified number you want).
2. Modify ServerSocket's HandleConnection () to generate a new THREAD with an instance of ConnectionHandler.
3. Borrowing the code of the RemoteFileServer's HandleConnection () method implementation of the Run () function of the ConnectionHandler class.