Day21 : TCP(一对一聊天、群聊、互联五子棋大战)、UDP一对一聊天、Http(互联网下载图片、查询快递)

    xiaoxiao2022-07-05  166

    #TCP

    通过三次握手建立连接

    Step 1:客户主机发送TCP SYN数据段到服务器(SYN=1,客户机制定起始序号seq=x)

    Step 2:服务器主机收到SYN,用SYN+ACK数据段响应(SYN=1,ACK=1,seq=y;ack=x+1)

    Step 3:客户收到SYN+ACK,用ACK数据段响应,可以包含数据(SYN=0,ACK=1,seq=x+1,ack=y+1)  (当SYN=1,ACK=0表明这是一个连接请求报文,对方若同意建立连接,则在响应报文中使用SYN=1,ACK=1。SYN=1表示这是一个连接请求或连接接收报文)

    释放连接过程

    Step 1:客户结束发送TCP FIN控制数据段到服务器(FIN=1,seq=u)

    Step 2:服务器收到FIN,用ACK响应。(ACK=1,seq=v,ack=u+1)

    Step 3:服务器发送FIN(FIN=1,ACK=1,seq=w,ack=u+1)

    Step 4:客户收到FIN,发送ACK确认关闭(ACK=1,seq=u+1,ack=w+1)

    ###1.TCP一对一聊天

    实现客户端与服务器的交互。通过多线程实现端的Receive和Send独立

    客户端

    public class Cilent { public static void main(String[] args) throws UnknownHostException, IOException { //创建连接 Socket socket = new Socket("127.0.0.1",19999); //创建输入输出流 Scanner scan = new Scanner(System.in); PrintStream ps = new PrintStream(socket.getOutputStream()); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); new Receive(socket).start(); while(true) { //向服务器发送消息 ps.println("客户端:"+scan.next()); } } }

    服务器

    public class Server { public static void main(String[] args) throws IOException { //创建连接 ServerSocket server = new ServerSocket(19999); Socket socket = server.accept(); //创建流 Scanner scan = new Scanner(System.in); PrintStream ps = new PrintStream(socket.getOutputStream()); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); new Receive(socket).start(); while(true) { //向客户端发送消息 ps.println("服务器:"+scan.next()); } } }

    接收线程

    public class Receive extends Thread{ private BufferedReader br; public Receive(Socket socket) throws IOException { br = new BufferedReader(new InputStreamReader(socket.getInputStream())); } @Override public void run() { while(true) { String readLine = null; try { readLine = br.readLine(); } catch (IOException e) {} System.out.println(readLine); } } }

     

    ###2.TCP群聊

    1.各客户端先与服务器建立连接

    2.连接以后就启动线程

    3.线程实现消息的接收与转发

    客户端

    public class Cilent { /** * 群聊 * 客户端发送一条消息,服务器将其内容转发给其他客户端 * */ public static void main(String[] args) throws UnknownHostException, IOException { //创建套接字 Socket socket = new Socket("127.0.0.1",19999); //创建流 Scanner scan = new Scanner(System.in); PrintStream ps = new PrintStream(socket.getOutputStream()); new Receive(socket).start(); //向服务器发送消息 while(true) { ps.println("客户端1:"+scan.next()); } } }

    服务器

    public class Server { public static ConcurrentHashMap<String, Socket> map = new ConcurrentHashMap<>(); public static void main(String[] args) throws IOException { /** * * 群聊:多个客户端与服务器连接 * 客户端:创建接收线程(为了与发送不冲突),while(true)循环向服务器发送信息 * 服务器:与多个客户端连接,每accept一次,就存储ConcurrentHashMap一次,并启动一个线程 * 利用多线程转发(每条线程都在不停地接收该客户端发送的信息并转发) * */ ServerSocket server = new ServerSocket(19999); //获取其他客户端的IP,Socket.存入HashMap中, while(true) { Socket socket = server.accept(); String ip = socket.getInetAddress().getHostAddress(); map.put(ip, socket); new MyThread(socket).start(); } } } //利用多线程像其他客户端转发 class MyThread extends Thread{ private Socket socket; public MyThread(Socket socket) { this.socket=socket; } @Override public void run() { BufferedReader br=null; try { br = new BufferedReader(new InputStreamReader(socket.getInputStream())); } catch (IOException e1) { } //循环接收来自客户端的消息 while(true) { try { String readLine = br.readLine(); System.out.println(readLine); //转发 Set<Entry<String,Socket>> entrySet=Server.map.entrySet(); for(Entry<String, Socket> entry:entrySet) { String key = entry.getKey(); Socket value = entry.getValue(); if(!key.equals(socket.getInetAddress().getHostAddress())) { PrintStream ps = new PrintStream(value.getOutputStream()); ps.println(readLine); } } } catch (IOException e) { } } } }

    接收线程

    public class Receive extends Thread{ private BufferedReader br; public Receive(Socket socket) throws IOException { br = new BufferedReader(new InputStreamReader(socket.getInputStream())); } @Override public void run() { while(true) { String readLine = null; try { readLine = br.readLine(); } catch (IOException e) {} System.out.println(readLine); } } }

    ###3.互联五子棋大战

    #UDP

    ###1.一对一聊天

    客户端1:

    public class Client01 { public static void main(String[] args) throws SocketException { DatagramSocket socket = new DatagramSocket(19321); new SendThread(socket,"127.0.0.1",19999,"UDP1号").start(); new ReceiveThread(socket).start(); } }

    客户端2号:

    public class Client02 { public static void main(String[] args) throws SocketException { DatagramSocket socket = new DatagramSocket(19999); new SendThread(socket,"127.0.0.1",19321,"UDP2号").start(); new ReceiveThread(socket).start(); } }

    发送线程

    public class SendThread extends Thread{ private DatagramSocket socket; private String ip; private int port; private String name; public SendThread(DatagramSocket socket, String ip, int port, String name) { this.socket = socket; this.ip = ip; this.port = port; this.name = name; } @Override public void run() { Scanner scan = new Scanner(System.in); while(true) { byte[] b = (name+":"+scan.nextLine()).getBytes(); DatagramPacket p; try { p = new DatagramPacket(b, b.length,InetAddress.getByName(ip),port); socket.send(p); } catch (IOException e) { } } } }

    接收线程

    public class ReceiveThread extends Thread{ private DatagramSocket socket; public ReceiveThread(DatagramSocket socket) { this.socket = socket; } @Override public void run() { while(true) { byte[] b = new byte[1024]; DatagramPacket p = new DatagramPacket(b, b.length); try { socket.receive(p); System.out.println(new String(b).trim()); } catch (IOException e) { } } } }

     

    #Http

    提供免费接口的网站www.bejson.com

    简述浏览器访问一个网页的过程?

    浏览器向服务器发出对该页面中所包含对象的HTTP请求报文;服务器接收请求并用包含这些对象的HTTP响应报文进行响应。

    ###1.互联网下载图片

    public class Test01 { public static void main(String[] args) throws IOException { //下载图片 URL url = new URL("https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1558505994&di=37a8fbb5b0494029230bf0a9c9fe71dc&src=http://www.deyu.ln.cn/images/obuwgobonzuxa2ldfzrw63i/20100709/5338161_083916003110_2.jpg"); //获取连接对象 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); //设置 connection.setConnectTimeout(5000);//设置超时连接时间 connection.setReadTimeout(5000);//设置超时读取时间 connection.setDoInput(true);//设置允许输入流 connection.setDoOutput(true);//设置允许输出流 connection.setRequestMethod("GET"); //获取响应码 int code = connection.getResponseCode(); if(code == HttpURLConnection.HTTP_OK) {//连接正确 InputStream in = connection.getInputStream(); FileOutputStream out = new FileOutputStream("葫芦娃.jpg"); //拷贝 byte[] b = new byte[1024]; int len; while((len = in.read(b))!=-1) { out.write(b,0,len); } out.close(); }else if(code == HttpURLConnection.HTTP_NOT_FOUND) { System.out.println("网页丢失了..."); } } }

     

    ###2.查询快递

    public class Test03 { public static void main(String[] args) throws IOException { //查快递 URL url = new URL("https://www.kuaidi100.com/query?type=zhongtong&postid=75145579929366"); //获取连接对象 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); //设置 connection.setConnectTimeout(5000);//设置超时连接时间 connection.setReadTimeout(5000);//设置超时读取时间 connection.setDoInput(true);//设置允许输入流 connection.setDoOutput(true);//设置允许输出流 connection.setRequestMethod("GET"); //获取响应码 int code = connection.getResponseCode(); if(code == HttpURLConnection.HTTP_OK) {//连接正确 //使用带编码格式的IO流 InputStreamReader isr = new InputStreamReader(connection.getInputStream(), "UTF-8"); //输出查询结果 char[] b = new char[1024]; int len; while((len = isr.read(b))!=-1) { System.out.println(new String(b).toCharArray()); } }else if(code == HttpURLConnection.HTTP_NOT_FOUND) { System.out.println("网页丢失了..."); } } }

     

    最新回复(0)