JAVA网络编程 ——基于TCP的Socket编程—实现服务器端与客户端的实时对话
一,HTTP与Socket
1.HTTP:超文本传输协议
特点:客户端发送的请求需要服务器端每次来响应,在请求结束之后主动释放连接,从建立连接到关闭连接称为“一次连接”,所以HTTP是“短连接”。
2.Socket(IP+PORT):是TCP/IP的封装与应用,它不是协议,而是API
特点:客户端与服务器之间一旦建立连接,就可以互相范松消息,也叫对话,但在实际应用中,通信双方经过许多的中间节点,比如,路由器,网关,防火墙,大部分防火墙会默认关闭长时间处于不活跃的状态连接,而是Socket断开。
选择:当服务器主要想客户端推送消息,为了保持客户端与服务器数据的实时与同步,通常会从采用HTTP协议,只要客户端定时向服务器端发送请求,同时也是在询问是否有新的数据,如果有那就传入客户端。
二,TCP/IP模型
1.通信原理图
2.模型图
三,基于TCP的网络编程
1.Socket: IP地址+端口号组成了Socket,Socket是网络上运行程序之间双向通信的终结点,是TCP和UDP的基础。
2.JAVA提供的网络功能(可以查看API)
InetAddress:标识IP地址
URL:统一资源定位,通过URL可以直接读取或写入网络上的数据
Sockets:使用TCP协议实现Socket相关的类
Datagram:使用UDP协议。将数据保存在数据包中,通过网络通信。
3.Socket通信模型
4.代码(可直接粘贴复制,使用)请修改包名
1.服务器端线程类 ServerThread.class
//*******************服务器端线程类********************// package com.NullChenHui; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; public class ServerThread extends Thread { private int port; private boolean OVER_FLAG = false; public ServerThread(int port) { this.port = port; } @Override public void run() { // TODO Auto-generated method stub /** * 使用无线循环或者有限循环来实现客户端与服务器的对话 */ try { //1.创建连接服务器的Socket 并绑定端口号 ServerSocket ssocket = new ServerSocket(port); while(!OVER_FLAG) { //2.监听来自客户端的请求 并返回Socket实例 Socket socket = ssocket.accept(); //3.获取输入流 InputStream is = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(is); //字节流包装为字符流 BufferedReader bf = new BufferedReader(isr); //添加进缓存 //4.从缓存中读取数据 String info = null; if("OVER".equals(info)) { OVER_FLAG = true; break; } while((info=bf.readLine()) != null) { System.out.println("客户端说:"+info); if("OVER".equals(info)) { OVER_FLAG = true; break; } } socket.shutdownInput(); String data = null; System.out.print("服务端:"); Scanner scanner = new Scanner(System.in); String data1 = scanner.nextLine(); //回馈给客户端 OutputStream os = socket.getOutputStream(); PrintWriter pw = new PrintWriter(os); //3.发送数据 pw.write(data1); pw.flush(); //4.关闭资源 os.close(); pw.close(); is.close(); bf.close(); // socket.shutdownOutput(); } System.out.println("对话结束"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
2.服务器端主程序 MyServerSocket.class
package com.NullChenHui; /** * 基于TCP的Socket的编程 服务端 * @author NullChen * */ public class MyServerSocket{ @SuppressWarnings("resource") public static void main(String[] args) { System.out.println("***我是服务器***"); ServerThread sThread = new ServerThread(3333); sThread.start(); } }
3.客户端线程类 ClientThread.class
package com.NullChenHui; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; import java.util.Scanner; public class ClientThread extends Thread { private String IP; private int port; private boolean OVER_FLAG = false; public ClientThread(String IP ,int port) { this.IP = IP; this.port = port; } @Override public void run() { // TODO Auto-generated method stub OutputStream os =null; PrintWriter pw = null; try { //1.建立客户端Socket 并指定发送服务器端的地址(IP + port ) //2.获取输出流 while(!OVER_FLAG) { Socket socket = new Socket(IP,port); os = socket.getOutputStream(); pw = new PrintWriter(os); //3.发送数据 System.out.print("客户端:"); Scanner scanner = new Scanner(System.in); String data1 = scanner.nextLine(); pw.write(data1); pw.flush(); //4.关闭资源 socket.shutdownOutput(); //接受来自服务器的反馈 InputStream is = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(is); //字节流包装为字符流 BufferedReader bf = new BufferedReader(isr); //添加进缓存 //4.从缓存中读取数据 String info = null; while((info=bf.readLine()) != null) { System.out.println("服务器说:"+info); if("OVER".equals(info)) { OVER_FLAG = true; break; } } /*** * 如果获取的内容是空的 说明服务器端还没有发送数据 */ // 5 关闭资源 os.close(); pw.close(); is.close(); bf.close(); // socket.shutdownInput(); } System.out.println("对话结束"); } catch (UnknownHostException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
4.客户端主程序 MyClientSocket.class
package com.NullChenHui; public class MyClientSocket{ public static void main(String[] args) { System.out.println("***我是客户端***"); ClientThread cThread = new ClientThread("127.0.0.1",3333); cThread.start(); } }
四,注意问题
1.先启动服务器端后启动客户端
2.两个之间的对话就是客户端说一句,服务器说一句。
3.以客户端以OVER结束对话
4.在关闭输入输出流的地方有点小问题。
五,java调用tcp socket接口
package com.autotest.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintWriter; import java.net.Socket; public class SocketUtil { /* * 获取socket连接 */ public static Socket getConnection(String ip, int port) { Socket socket = null; try { socket = new Socket(ip, port); socket.setSoTimeout(30000); } catch (IOException e) { e.printStackTrace(); } return socket; } /* * 发送报文 */ public static String send(Socket socket, String cmd) { InputStream in = null; OutputStream out = null; BufferedReader br = null; try { // in代表服务器到客户端的流 in = socket.getInputStream(); // 代表客户端到服务器的流 out = socket.getOutputStream(); // 输入执行命令 PrintWriter printWriter = new PrintWriter(out, true); printWriter.println(cmd); printWriter.flush(); // 接收执行命令结果 br = new BufferedReader(new InputStreamReader(in)); return br.readLine(); } catch (IOException e) { e.printStackTrace(); } finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } return null; } /* * 关闭socket连接 */ public static void close(Socket socket) { if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } /* * 测试代码 */ public static void main(String args[]){ String result=""; Socket socket=null; String cmd="New 100004341413830 "; try { socket=SocketUtil.getConnection("192.168.1.100", 10000); String resultStr=SocketUtil.send(socket, cmd); String resultArr[]=resultStr.split(" "); resultStr=resultArr[1].substring(1, resultArr[1].length()-1); if("OK".equals(resultStr)){ result="成功"; }else { result="失败"; } System.out.println(result); } catch (Exception e) { SocketUtil.close(socket); } } }

浙公网安备 33010602011771号