1,Socket的应用
java实现tcp通信主要通过Socket类。当客户端想要打开一个连接到服务器的TCP/IP连接时,就要使用到Socket类。socket类只需要被告知连接的IP地址和TCP端口,其余的都有Java实现。假如我们想要打开一个监听服务,来监听客户端连接某些指定TCP端口的连接,那就需要使用ServerSocket类。当客户端通过Socket连接服务器端的ServerSocket监听时,服务器端会指定这个连接的一个Socket,此时客户端与服务器端间的通信就变成Socket与Socket之间的通信。
利用ServerSocket获取一个Socket时线程会阻塞,除非有一个新的连接进来。下面程序中的handler方法中的read也会阻塞,除非有新的数据写入进来。所以当一个客户端连接进来没有退出时,会阻塞在read上,等待写入。这时候其它客户端没法连进来。所以可以在handler上使用多线程来处理。accept不需要理会它的阻塞,只要有新连接进来就OK。所以可以使用注释中的线程池来解决多客户端连接的问题。
public class Server2 { @SuppressWarnings("resource") public static void main(String[] args) throws Exception { //ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(); //创建socket服务,监听9000端口 ServerSocket server=new ServerSocket(9000); System.out.println("server start..."); while(true){ //获取一个套接字(阻塞) final Socket socket = server.accept(); System.out.println("来个一个新客户端!"); /*newCachedThreadPool.execute(new Runnable() { @Override public void run() { //业务处理 handler(socket); } });*/ handler(socket); } } /** * 读取数据 * @param socket * @throws Exception */ public static void handler(Socket socket){ try { byte[] bytes = new byte[1024]; InputStream inputStream = socket.getInputStream(); while(true){ //读取数据(阻塞) int read = inputStream.read(bytes); if(read != -1){ System.out.println(new String(bytes, 0, read)); }else{ System.out.println("disconnection"); break; } } } catch (Exception e) { e.printStackTrace(); }finally{ try { System.out.println("socket关闭"); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
这两个类可以用来创建客户端到web服务器(HTTP服务器)的连接。下面利用这两个类发起了一个get请求
URL url = new URL("http://jenkov.com"); URLConnection urlConnection = url.openConnection(); InputStream input = urlConnection.getInputStream(); int data = input.read(); while(data != -1){ System.out.print((char) data); data = input.read(); } input.close();
如果你想发送一个HTTP POST请求,要调用URLConnection.setDoOutput(true)方法,一旦你调用了setDoOutput(true),你就可以打开URLConnection的OutputStream,如下:
OutputStream output = urlConnection.getOutputStream();
你可以使用这个OutputStream向相应的HTTP请求中写任何数据,但你要记得将其转换成URL编码。具体名字是:application/x-www-form-urlencoded MIME 格式编码)使用这种方式发HTTP请求容易导致断码,还是使用HttpClient包好一点。