zoukankan      html  css  js  c++  java
  • 网络编程1-TCP编程(socket)

    1 如何实现网络中的主机相互通信

    一定的规则,有两套参考模型

    (1)osi参考模型,过于理想化,未能在互联网上推行

    osi有七层

    (2)tcp/ip参考模型,有四层,各层之间通过不同的网络协议传输数据。

    应用层: http协议

    传输层:TCP UDP协议

    网络层:IP协议

    物理+数据链路层:Link协议

    (3)截图?

    2   通信要素一 定位计算机

    (1)IP定位互联网上唯一计算机

    (2)端口号定位计算机上的应用

    (3)定位IP地址和端口号,java类InetAddress可以创建IP类

    要素二 在按照协议传输

      传输层有两个重要的协议,TCP/IP协议  UDP协议

      TCP协议:三次握手,客户端服务端,可靠,大数据,效率低

      (1)使用以前,先建立TCP链接,形成通道

      (2)传输前采取三次握手,是可靠的,A给B传输,A先给B发信息,B回复A,A开始传输。

      (3)TCP协议通信有两个进程,客户端,服务端

      (4)可进行大数据传输

      (5)传输完毕,需要释放已将建立的链接,效率低。

      UDP协议:

      (1)将数据、源地址、目的地址 封装成数据包,不需要建立链接

      (2)每个数据包限制在64K以内

      (3)不可靠

      (4)无需释放资源,速度快

    3、SOCKET套接字

    (1)socket是两台机器间通信的端点

    (2)socket允许把网络链接当成一个流,数据在两个socket之间通过IO传输

    (3)主动发起请求的是客户端,等待请求的是服务端

    4、(1)例1,客户端发送请求,服务端接收打印到控制台

    package com.socket.test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.InetAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    import org.junit.Test;
    
    //客户端给服务端发送信息,服务端输出信息到控制台上
    public class TCPTest {
        
        //客户端
        @Test
        public void client(){
            //1、创建Socket套接字
            Socket socket = null;
            //2、获取输出流
            OutputStream os = null;
            try {
                socket = new Socket(InetAddress.getByName("127.0.0.1"),8090);
                os = socket.getOutputStream();
                //3、向服务端写消息
                os.write("I am Client".getBytes());
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                //4、关闭流,套接字
                if(socket != null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if(os != null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
        
        
        @Test
        public void server(){
            Socket socket = null;
            InputStream is = null;
            ServerSocket ss = null;
            try {
                //1、创建ServerSocket对象,指定端口号
                ss = new ServerSocket(8090);
                
                //2、接收socket
                 socket = ss.accept();
                //3、获取输入流
                 is = socket.getInputStream();
                //4、读取
                byte[] b = new byte[20];
                int len;
                while((len = is.read(b)) != -1){
                    String str = new String(b,0,len);
                    System.out.print(socket.getInetAddress().getHostAddress()+"says"+str);
                }
                System.out.println("123");
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                if(socket != null ){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if(ss != null){
                    try {
                        ss.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if(is != null){
                    try {
                        is.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
            
            
        }
    }

    (2)例2,客户端向务务端发送请求,服务端应答

    package com.socket.test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.InetAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    import org.junit.Test;
    
    /*
     * 向服务端写消息,服务端收到消息后返回消息
     */
    public class TCPTest1 {
    
        @Test
        public void client(){
            Socket socket = null;
            OutputStream os = null;
            InputStream is = null;
            try {
                InetAddress inetObj = InetAddress.getByName("127.0.0.1");
                socket = new Socket(inetObj,8090);
                os = socket.getOutputStream();
                
                os.write(("Hello I am " + inetObj.getHostName()).getBytes());
                os.flush();
                //注意,这里的os不关闭,服务端对应的is.read()方法就会一直处于阻塞状态,无法往下执行,
                //所以我们要告诉服务端的inputstream,我这里不会再写了,服务端的is就不会再等待,
                //执行此方法,显示告诉服务器,客户端发送完毕
                socket.shutdownOutput();
                is = socket.getInputStream();
                byte[] b = new byte[20];
                int len;
                while((len = is.read(b)) != -1){
                    System.out.println("收到服务状的消息"+new String(b,0,len));
                }
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                if( os!= null){
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if( socket!= null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            
                if(is != null){
                    try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            
            
        }
    
        @Test
        public void server() {
            ServerSocket serverSocket = null;
            Socket socket = null;
            
            try {
                 serverSocket = new ServerSocket(8090);
                while(true){
                    socket = serverSocket.accept();
                    handleSocket(socket);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                if(serverSocket != null){
                    try {
                        serverSocket.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
        
        public void handleSocket(Socket socket){
            InputStream is = null;
            OutputStream os = null;
            try {
                is = socket.getInputStream();
                byte[] b = new byte[20];
                int len;
                StringBuffer sbr = new StringBuffer();
                while((len = is.read(b)) != -1){
                    sbr.append(new String(b,0,len));
                }
                System.out.println("客户端说:"+sbr.toString());
                os = socket.getOutputStream();
                os.write(sbr.toString().toUpperCase().getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                if(os != null){
                    try {
                        os.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if(is != null){
                    try {
                        is.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if(socket != null){
                    try {
                        socket.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
            
             
            
        }
    }

    (3)客户端发送文件到服务端,服务端接收完毕后,告诉客户端 ,接收完毕

    package com.socket.test;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.InetAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    import org.junit.Test;
    
    //客户端发送文件给服务端
    public class TcpTest2 {
    
        @Test
        public void fileClient() {
            // 1、创建socket对象
            Socket socket = null;
            // 2、获取输出流
            OutputStream os = null;
            // 3、先读,把本地文件读入输入流
            FileInputStream fis = null;
    
            InputStream is = null;
            try {
                socket = new Socket(InetAddress.getByName("127.0.0.1"), 8090);
                os = socket.getOutputStream();
                fis = new FileInputStream(new File("d://env.conf"));
                byte[] b = new byte[64];
                int len;
                while ((len = fis.read(b)) != -1) {
                    // 4、往外写
                    os.write(b, 0, len);
                }
                // 5、告诉服务器写完了
                socket.shutdownOutput();
                // 6、读取从服务器返回的消息
                is = socket.getInputStream();
                byte[] b1 = new byte[20];
                int len1;
                while ((len1 = is.read(b1)) != -1) {
                    System.out.print(new String(b1, 0, len1));
                }
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if (os != null) {
                    try {
                        os.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
    
            }
    
        }
    
        @Test
        public void fileServer() {
            ServerSocket ss = null;
            try {
                ss = new ServerSocket(8090);
                while(true){
                    Socket socket = ss.accept();
                    handleClient(socket);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally{
                try {
                    if(ss != null){
                        ss.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            
        }
        
        public void handleClient(Socket socket){
            //1、获取输入流
            InputStream is = null;
            //2、创建fileoutputStream对象
            FileOutputStream fos = null;
            
            OutputStream os = null;
            try {
                is = socket.getInputStream();
                fos = new FileOutputStream(new File("d://env1.conf"));
                //3、读取服务器发来的字节
                int len;
                byte b [] = new byte[64];
                while((len = is.read(b)) != -1){
                    fos.write(b, 0, len);
                }
                fos.flush();
                //4、写文件完毕,获取socket的输出流给客户端返回消息
                os = socket.getOutputStream();
                os.write("Accepted Over !".getBytes());
                os.flush();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
    
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if (os != null) {
                    try {
                        os.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
    
            
            }
            
            
             
        }
    }

    5、socket通信原理

    客户端,创建出一个socket对象时(创建InetAddress对象时,传入的ip是服务器的ip),服务端也接受到一个socket对象

    通过socket可以获取输入流和输出流

    ,客户端通过socket对象的输出流往服务器端写数据,

    服务器端通过socket对象的输入流读数据

    服务器服务端的通信,实际是sockey里面IO流的通信。

    要注意的是,Inputsream的read方法,和ServetSocket的accept方法是阻塞方法。

    6、聊天室的做法

    1)客户端发送自己的名字a,消息,送达人的名字b,拼接成一个字符串。

    2)服务端,接到a的请求,截取字符串,把a和a对应的socket对象放到map里面,然后启动一个线程,传入b .socket,

    3)线程里面,通过b从map里面获取b的socket,获取b的输出流,把a和a说的话写出去

    4)客户b的输入流接受到输出流发来的消息,结束。

    7、需要注意的事项都写在注释里面,下面放一张时序图,画的不太标准

  • 相关阅读:
    30 Day Challenge Day 18 | Leetcode 200. Number of Islands (BFS)
    30 Day Challenge Day 18 | Leetcode 701. Insert into a Binary Search Tree
    30 Day Challenge Day 17 | Leetcode 261. Graph Valid Tree
    30 Day Challenge Day 17 | Leetcode 559. Maximum Depth of N-ary Tree
    30 Day Challenge Day 17 | Leetcode 133. Clone Graph
    30 Day Challenge Day 17 | Leetcode 126. Word Ladder II
    30 Day Challenge Day 17 | Leetcode 489. Robot Room Cleaner
    30 Day Challenge Day 17 | Leetcode 127. Word Ladder
    30 Day Challenge Day 17 | Leetcode 624. Maximum Distance in Arrays
    30 Day Challenge Day 16 | Leetcode 701. Insert into a Binary Search Tree
  • 原文地址:https://www.cnblogs.com/fubaizhaizhuren/p/socket.html
Copyright © 2011-2022 走看看