Java Socket编程
Java Socket编程
对于Java Socket编程而言,有两个概念,一个是ServerSocket,一个是Socket。服务端和客户端之间通过Socket建立连接,之后它们就可以进行通信了。首先ServerSocket将在服务端监听某个端口,当发现客户端有Socket来试图连接它时,它会accept该Socket的连接请求,同时在服务端建立一个对应的Socket与之进行通信。这样就有两个Socket了,客户端和服务端各一个。
对于Socket之间的通信其实很简单,服务端往Socket的输出流里面写东西,客户端就可以通过Socket的输入流读取对应的内容。Socket与Socket之间是双向连通的,所以客户端也可以往对应的Socket输出流里面写东西,然后服务端对应的Socket的输入流就可以读出对应的内容。下面来看一个服务端与客户端通信的例子:
多个客户端连接同一个服务端
每次ServerSocket</span>接收到一个新的Socket</span>连接请求后都会新起一个线程来跟当前Socket</span>进行通信,这样就达到了异步处理与客户端Socket</span>进行通信的情况。我们使用</span>BufferedReader</span>来一次读一行,而不是一次读多少字节</span>
</div> </div>
这个时候需要注意的是,BufferedReader</span>的readLine</span>方法是一次读一行的,这个方法是阻塞的,直到它读到了一行数据为止程序才会继续往下执行,那么readLine</span>什么时候才会读到一行呢?直到程序遇到了换行符或者是对应流的结束符</span>readLine</span>方法才会认为读到了一行,才会结束其阻塞,让程序继续往下执行。所以我们在使用BufferedReader</span>的readLine</span>读取数据的时候一定要记得在对应的输出流里面一定要写入换行符(流结束之后会自动标记为结束,readLine</span>可以识别),写入换行符之后一定记得如果输出流不是马上关闭的情况下记得flush</span>一下,这样数据才会真正的从缓冲区里面写入。对应上面的代码我们的客户端程序应该这样写:</span>
客户端:
假设有这样一种需求,我们的客户端需要通过Socket从服务端获取到XX信息,然后给用户展示在页面上。我们知道Socket在读数据的时候是阻塞式的,如果没有读到数据程序会一直阻塞在那里。在同步请求的时候我们肯定是不能允许这样的情况发生的,这就需要我们在请求达到一定的时间后控制阻塞的中断,让程序得以继续运行。Socket为我们提供了一个setSoTimeout()方法来设置接收数据的超时时间,单位是毫秒。当设置的超时时间大于0,并且超过了这一时间Socket还没有接收到返回的数据的话,Socket就会抛出一个SocketTimeoutException。
假设我们需要控制我们的客户端在开始读取数据10秒后还没有读到数据就中断阻塞的话我们可以这样做:
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.Writer; import java.net.Socket; import java.net.SocketTimeoutException; public class Client { public static void main(String args[]) throws Exception { //为了简单起见,所有的异常都直接往外抛 String host = "127.0.0.1"; //要连接的服务端IP地址 int port = 8899; //要连接的服务端对应的监听端口 //与服务端建立连接 Socket client = new Socket(host, port); //建立连接后就可以往服务端写数据了 Writer writer = new OutputStreamWriter(client.getOutputStream()); writer.write("Hello Server."); writer.write("eof\n"); writer.flush(); //写完以后进行读操作 BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream())); //设置超时间为10秒 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("数据读取超时。"); } System.out.println("from server: " + sb); writer.close(); br.close(); client.close(); } }
来自:http://haohaoxuexi.iteye.com/blog/1979837