其实web 开发的底层就是socket 编程
数据是通过流读取
服务端
public class WeatherServer { public static void main(String[] args) throws IOException { // 创建socket 服务,应用服务端口建议在1万以上 ServerSocket server = null; Socket socket = null; DataInputStream di=null ; DataOutputStream ds=null ; try { server = new ServerSocket(12345); // 按受客户端链接 socket = server.accept(); //为了好处理字符串 // 接受客户端请求 di=new DataInputStream(socket.getInputStream()); // 向服务端发送请求 ds=new DataOutputStream(socket.getOutputStream()); //客户端向服务端发送的天气所在城市 String cityName =di.readUTF(); System.out.println("from client...."+cityName); //服务端向客户端返回天气情况 String result ="晴"; ds.writeUTF("晴"); System.out.println("to client...."+result); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { di.close(); ds.close(); //服务端一般是不关闭资源的,由客户端关闭 //socket.close(); } } }
客户端代码:
public class WeatherClient { public static void main(String[] args) throws UnknownHostException, IOException { Socket client = null; DataInputStream di = null; DataOutputStream ds = null; client = new Socket("127.0.0.1", 12345); try { // 接受客户端请求 di = new DataInputStream(client.getInputStream()); // 向服务端发送请求 ds = new DataOutputStream(client.getOutputStream()); String cityName ="北京"; ds.writeUTF(cityName); String result =di.readUTF(); System.out.println("接受服务端.."+result); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { di.close() ; ds.close(); client.close(); } } }
其实服务端开发要有可持续能力,保证线程一直在运行,那么上面的代码就可以改成这样:
public class WeatherServerV2 { public static void main(String[] args) throws IOException { // 创建socket 服务,应用服务端口建议在1万以上 ServerSocket server = null; Socket socket = null; DataInputStream di=null ; DataOutputStream ds=null ; while(true){ try { server = new ServerSocket(12345); // 按受客户端链接 socket = server.accept(); //为了好处理字符串 // 接受客户端请求 di=new DataInputStream(socket.getInputStream()); // 向服务端发送请求 ds=new DataOutputStream(socket.getOutputStream()); //客户端向服务端发送的天气所在城市 String cityName =di.readUTF(); System.out.println("from client...."+cityName); //服务端向客户端返回天气情况 String result ="晴"; ds.writeUTF("晴"); System.out.println("to client...."+result); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { di.close(); ds.close(); //服务端一般是不关闭资源的,由客户端关闭 //socket.close(); } } } }
同样的道理,服务端不仅要有持续运行能力,还要有处理并发的能力,我们可以把客户端也改成死循环
public class WeatherClientVersion2 { public static void main(String[] args) throws UnknownHostException, IOException { Socket client = null; DataInputStream di = null; DataOutputStream ds = null; client = new Socket("127.0.0.1", 12345); while(true){ try { // 接受客户端请求 di = new DataInputStream(client.getInputStream()); // 向服务端发送请求 ds = new DataOutputStream(client.getOutputStream()); String cityName ="北京"; ds.writeUTF(cityName); String result =di.readUTF(); System.out.println("接受服务端.."+result); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { di.close() ; ds.close(); client.close(); } } } }
但是上面属于单线程的问题,所以我们要用多线程
public class WeatherServerV3 { public static void main(String[] args) throws IOException { //创建socket服务端 //应用服务端口建议在1万以上 ServerSocket serverSocket = new ServerSocket(12999); System.out.println("启动天气查询服务..."); while(true){ try { //接收客户端链接 //阻塞方法 Socket socket = serverSocket.accept(); //开户一个新线程 //新线程处理内容就是,接收客户端请求数据,向客户端发送数据 //可以使用线程池 //使用ThreadPoolExecutor new Thread(new WeatherRun(socket)).start(); } catch (Exception e) { e.printStackTrace(); }finally{ //释放资源 // dataInputStream.close(); // // dataOutputStream.close(); //服务端一般不主动关闭socket //socket.close(); } } } }
实现多线程的Runnable 接口
public class WeatherRun implements Runnable { private Socket socket = null; DataInputStream di = null; DataOutputStream ds = null; public WeatherRun() { } public WeatherRun(Socket socket) { this.socket = socket; } @Override public void run() { // 按受客户端链接 try { // 为了好处理字符串 // 接受客户端请求 di = new DataInputStream(socket.getInputStream()); // 向服务端发送请求 ds = new DataOutputStream(socket.getOutputStream()); // 客户端向服务端发送的天气所在城市 String cityName = di.readUTF(); System.out.println("启动天气查询。。"); System.out.println("from client...." + cityName); // 服务端向客户端返回天气情况 String result = "晴"; ds.writeUTF("晴"); System.out.println("to client...." + result); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { /*try { //di.close(); //ds.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }*/ } } }