当客户程序需要与服务器程序通讯的时候客户程序在客户机创建一个socket对象Socket类有几个构造函数
两个常用的构造函数是 Socket(InetAddress addr int port) 和 Socket(String host int port)两个构造函数都创建了一个基于Socket的连接服务器端流套接字的流套接字对于第一个InetAddress子类对象通过addr参数获得服务器主机的IP地址对于第二个函数host参数包被分配到InetAddress对象中如果没有IP地址与host参数相一致那么将抛出UnknownHostException异常对象两个函数都通过参数port获得服务器的端口号假设已经建立连接了网络API将在客户端基于Socket的流套接字中捆绑客户程序的IP地址和任意一个端口号否则两个函数都会抛出一个IOException对象
如果创建了一个Socket对象那么它可能通过调用Socket的 getInputStream()方法从服务程序获得输入流读传送来的信息也可能通过调用Socket的 getOutputStream()方法获得输出流来发送消息在读写活动完成之后客户程序调用close()方法关闭流和流套接字下面的代码创建了一个服务程序主机地址为端口号为的Socket对象然后从这个新创建的Socket对象中读取输入流然后再关闭流和Socket对象
Socket s = new Socket ( );InputStream is = sgetInputStream ();// Read from the streamisclose (); sclose ();
接下面我们将示范一个流套接字的客户程序这个程序将创建一个Socket对象Socket将访问运行在指定主机端口上的服务程序如果访问成功客户程序将给服务程序发送一系列命令并打印服务程序的响应List使我们创建的程序SSClient的源代码
Listing : SSClientjava
// SSClientjavaimport javaio*;import *; class SSClient{public static void main (String [] args){String host = localhost;// If user specifies a commandline argument that argument// redivsents the host nameif (argslength == )host = args [];BufferedReader br = null;PrintWriter pw = null;Socket s = null;try{// Create a socket that attempts to connect to the server// program on the host at port s = new Socket (host );// Create an input stream reader that chains to the sockets// byteoriented input stream The input stream reader// converts bytes read from the socket to characters The// conversion is based on the platforms default character// setInputStreamReader isr;isr = new InputStreamReader (sgetInputStream ());// Create a buffered reader that chains to the input stream// reader The buffered reader supplies a convenient method// for reading entire lines of textbr = new BufferedReader (isr);// Create a print writer that chains to the sockets byte// oriented output stream The print writer creates an// intermediate output stream writer that converts// characters sent to the socket to bytes The conversion// is based on the platforms default character setpw = new PrintWriter (sgetOutputStream () true);// Send the DATE command to the serverpwprintln (DATE);// Obtain and print the current date/timeSystemoutprintln (brreadLine ());// Send the PAUSE command to the server This allows several// clients to start and verifies that the server is spawning// multiple threadspwprintln (PAUSE);// Send the DOW command to the serverpwprintln (DOW);// Obtain and print the current day of weekSystemoutprintln (brreadLine ());// Send the DOM command to the serverpwprintln (DOM);// Obtain and print the current day of monthSystemoutprintln (brreadLine ());// Send the DOY command to the serverpwprintln (DOY);// Obtain and print the current day of yearSystemoutprintln (brreadLine ());}catch (IOException e){Systemoutprintln (etoString ());}finally{try{if (br != null)brclose ();if (pw != null)pwclose ();if (s != null)sclose ();}catch (IOException e){}}} }
运行这段程序将会得到下面的结果
Tue Jan :: CST
TUESDAY
SSClient创建了一个Socket对象与运行在主机端口的服务程序联系主机的IP地址由host变量确定SSClient将获得Socket的输入输出流围绕BufferedReader的输入流和PrintWriter的输出流对字符串进行读写操作就变得非常容易SSClient个服务程序发出各种date/time命令并得到响应每个响应均被打印一旦最后一个响应被打印将执行Try/Catch/Finally结构的Finally子串Finally子串将在关闭Socket之前关闭BufferedReader 和 PrintWriter
在SSClient源代码编译完成后可以输入java SSClient 来执行这段程序如果有合适的程序运行在不同的主机上采用主机名/IP地址为参数的输入方式比如是运行服务器程序的主机那么输入方式就是java SSClient
技巧
Socket类包含了许多有用的方法比如getLocalAddress()将返回一个包含客户程序IP地址的InetAddress子类对象的引用;getLocalPort()将返回客户程序的端口号;getInetAddress()将返回一个包含服务器IP地址的InetAddress子类对象的引用getPort()将返回服务程序的端口号