Socket是网络编程中最基本的通信接口,常用的网络辅助类,比如URL等之类,其底层还是基于Socket来实现的。
而Socket,形象来说,就是连接通信的两端,比如这样 S<==>S,中间的通道就是网络了,而简单地利用Socket,我们就可以来实现一个简单的聊天功能
具体效果看下图:
这只是在本地中试用的效果,如果加上UI界面,其实就可以做成一个聊天的小应用了。
1. Server 端主要是利用ServerSocket的accept方法来等待客户端的连接,如果客户一直没有连接,则会在这里等待,直到客户端请求到来。
而客户端就是一个Socket,当客户端请求到来的时候,accept会返回一个Socket对象, 这就是S<==>S中的左边那个S了,可以利用其InputStream和OutputStream来进行读写了,读就是接收信息,而写就是回复信息。
代码如下 | 复制代码 |
public class Server { public static void main(String[] args) { try { ServerSocket server = new ServerSocket(9999); Helper.println("Server started, waiting for message."); Socket client = server.accept(); PrintWriter pw = null; while (true) { BufferedReader br = new BufferedReader(new InputStreamReader( client.getInputStream())); String content = br.readLine(); if (content.equals("end")) { server.close(); br.close(); if (pw != null) { pw.close(); } break; } Helper.println(content); Helper.print("Server:"); pw = new PrintWriter(client.getOutputStream(), true); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); String output = "Server : " + in.readLine(); pw.println(output); pw.flush(); } Helper.println("Client left! Server Closed."); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } |
2. Client端就是一个Socket,并定义一个连接的地址和端口,地址表明是网络中哪一台主机,而端口则表明了是主机中的那个应用程序,很显然就是上面Server这个应用,因为其定义了其等待监听的端口就是9999.当创建了一个Socket对象,并指定了地址和端口的时候,其实就已经发送了一个请求去对应的Server,请求连接,而如果连接成功,就可以继续下去,不然直接抛出异常。当然,这里连接成功,必须是Server先在监听了。[java] view plaincopy
代码如下 | 复制代码 |
public class Client { public static void main(String[] args) { try { Socket client = new Socket("127.0.0.1", 9999); PrintWriter pw = null; InputStreamReader isr = null; Helper.println("Client started, ready to write content."); String input = ""; while (true) { Helper.print("Client : "); InputStream is = System.in; input = new BufferedReader(new InputStreamReader(is)) .readLine(); pw = new PrintWriter(client.getOutputStream(), true); pw.println("Client:" + input); if (input.equals("end")) { client.close(); is.close(); pw.close(); if (isr != null) { isr.close(); } break; } isr = new InputStreamReader(client.getInputStream()); Helper.println(new BufferedReader(isr)。readLine()); } Helper.println("Client stopped!"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } |
ps:java.net.Socket继承于java.lang.Object,有八个构造器,其方法并不多,下面介绍使用最频繁的三个方法,其它方法大家可以见JDK-1.3文档。
. Accept方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。"阻塞"是一个术语,它使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。
. getInputStream方法获得网络连接输入,同时返回一个InputStream对象实例。
. getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。
注意:其中getInputStream和getOutputStream方法均会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。