Java程序辅导

C C++ Java Python Processing编程在线培训 程序编写 软件开发 视频讲解

客服在线QQ:2653320439 微信:ittutor Email:itutor@qq.com
wx: cjtutor
QQ: 2653320439
SSC1 - sockets Sockets What Is a Socket? A socket is one end-point of a two-way communication link between two programs running on the network. Socket classes are used to represent the connection between a client program and a server program. The java.net package provides two classes - Socket and ServerSocket - that implement the client side and the server side of the connection, respectively. The internet is a special example of a socket-based system - normal web applications run on port 80 and use the HTTP protocol, and there are specialised java classes to access it. The approach to working with sockets are much the same as with the Internet: Open a socket. Open an input stream and output stream to the socket. Read from and write to the stream according to the server's protocol. Close the streams. Close the socket. Only step 3 differs from client to client, depending on the server. The other steps remain largely the same. The main classes used are Socket for the client side and ServerSocket for the server side - as ever, the Javadoc gives us all the information we need to use these classes successfully. Client side - Socket There are multiple constructors for sockets, allowing the programmer to create a socket from a variety of parameters. The class also provides methods (as you'll be expecting, by now) called getInputStream() and getOutputStream() which allow you to read and write to the socket, along with a number of other housekeeping and option setting calls. There is also a close() call, to allow the system to neatly shut the socket down. Example import java.io.*; import java.net.*; public class EchoClient { public static void main(String[] args) throws IOException { Socket echoSocket = null; PrintWriter out = null; BufferedReader in = null; try { echoSocket = new Socket("examplemachine", 7); out = new PrintWriter(echoSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream())); } catch (UnknownHostException e) { System.err.println("Don't know about host: taranis."); System.exit(1); } catch (IOException e) { System.err.println("Couldn't get I/O for " + "the connection to: taranis."); System.exit(1); } BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); String userInput; while ((userInput = stdIn.readLine()) != null) { out.println(userInput); System.out.println("echo: " + in.readLine()); } out.close(); in.close(); stdIn.close(); echoSocket.close(); } } Walkthrough The blue code reserves space for some of the basic objects in the system. The try - catch copes with the exceptions thrown by the networking. The interesting code is the red stuff: the dark red creates a socket on machine name examplemachine on port 7, whilst the lighter red code uses the getOutputStream() and getInputStream() methods to get the relevant streams, and wraps them in PrintWriter and BufferedReader so that there are some nice methods available for use. We then open System.in for reading, and then read lines from it in the green code. The purple highlighting does the interesting stuff as far as the sockets are concerned: the first uses out (which is a PrintWriter connected to the socket for sending infomation, remember) to send the information straight to the socket. Whatever is on the other end of that socket then processes it - the result is then available to be read, and is printed out to the screen via in.readLine(). And what does the server do? In this case, it's the Echo server, which simply returns back what was sent to it, and always listens on port 7. The final lines of code do neat housekeeping and close the streams and then the sockets. Server side - ServerSocket Clients aren't much use unless they can talk to a server. To create a Socket, you need to know the Internet host to which you want to connect. When you're writing a server, you don't know in advance who will contact you, and even if you did, you wouldn't know when. Servers are like receptionists who sit by the phone and wait for incoming calls. They don't know who will call or when, only that when the phone rings, they have to pick it up and talk to whoever is there. A server socket's job is to sit by the phone and wait for incoming calls. More technically, a ServerSocket runs on the server and listens for incoming TCP connections. Each ServerSocket listens on a particular port on the server machine. When a client Socket on a remote host attempts to connect to that port, the server wakes up, negotiates the connection between the client and the server, and opens a regular Socket between the two hosts. In other words, server sockets wait for connections while client sockets initiate connections. Once the server socket has set up the connection, the server uses a regular Socket object to send data to the client. Data always travels over the regular socket. Note that java client programs that use sockets do not need to communicate with only Java servers - they do not care what the language used is - it's only the protocol between them that they must agree on. The general approach is shown below: A new ServerSocket is created on a particular port using a ServerSocket( ) constructor. The ServerSocket listens for incoming connection attempts on that port using its accept( ) method. accept( ) blocks until a client attempts to make a connection, at which point accept( ) returns a Socket object connecting the client and the server. Depending on the type of server, either the Socket's getInputStream( ) method, getOutputStream( ) method, or both are called to get input and output streams that communicate with the client. The server and the client interact according to an agreed-upon protocol until it is time to close the connection. The server, the client, or both close the connection. The server returns to step 2 and waits for the next connection. If step 4 is likely to take a long time, then it is usual to create a thread to handle other incoming connection requests, else the server will not respond to other clients until the current one has finished. Advanced: what happens to the requests until they are serviced? Which part of the system deals with this? Example try { ServerSocket httpd = new ServerSocket(80); } catch (IOException e) { System.err.println(e); } creates a ServerSocket on port 80 - the start of the code we'd write to create a web server application..... The constructor throws an IOException (specifically, a BindException) if the socket cannot be created and bound to the requested port. If you get one of these, it meanes either another server socket, possibly from a completely different program, is already using the requested port, or you're trying to connect to a port from 1 to 1023 on Unix without root (superuser) privileges. We can use the exception to write a basic port scanner to see what ports are in use on your machine: import java.net.*; import java.io.*;   public class LocalPortScanner {   public static void main(String[] args) { for (int port = 1; port <= 65535; port++) {   try { // the next line will fail and drop into the catch block if // there is already a server running on the port ServerSocket server = new ServerSocket(port); } catch (IOException e) { System.out.println("There is a server on port " + port + "."); }  }  } } This program uses the exception to actually do the work.   Accepting a connection ServerSocket server = new ServerSocket(5776); while (true) { Socket connection = server.accept( ); OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream( )); out.write("You've connected to this server. Bye-bye now.\r\n"); connection.close( ); } If you don't want your program to halt while it waits for a connection, put the call to accept( ) in a separate thread.   Exception handling Exceptions should be handled differently, depending on which object throws them. Exceptions thrown by the ServerSocket should probably shut down the server and log an error message. Exceptions thrown by a Socket should just close that active connection. Exceptions thrown by the accept( ) method are an intermediate case that can go either way. To do this, you'll need to nest the try blocks. Finally, most servers will want to make sure that all sockets they accept are closed when they're finished. Even if the protocol specifies that clients are responsible for closing connections, clients do not always strictly adhere to the protocol. The call to close( ) also has to be wrapped in a try block that catches an IOException. However, if you do catch an IOException when closing the socket, ignore it. It just means that the client closed the socket before the server could. Advanced: Try writing an echo server that returns whatever is set to it. You may want to use the port scanner to identify a free port to set it up on. Don't forget to alter your echoclient code to connect to your new server.