Socket

Socket编程

1基础知识

协议 端口号(辨别不同应用)

image

TCP/IP协议

是目前世界上应用最广泛的协议
是以TCP为基础的不同层次上多个协议的集合

也称:TCP/IP协议族 或 TCP/IP协议栈

TCP:Transmission Control Protocol 传输控制协议

IP: Internet Protocol 互联网协议

image

IP地址

为实现网络中不同计算机之间的通信,每台机器都必须有唯一的标识—-IP地址

IP地址格式:数字型:192.168.1.10

端口

1、用来区分不同应用程序,每个应用都会有个端口号

2、端口的范围065535,其中01023为系统保留

3、IP地址和端口号组成了所谓的Socket,Socket是网络上运行的程序之间双向通信链路的终结点,是TCP和UDP的基础。

4、常见协议端口号 http:80 ftp:21 telnet:23

JAVA中的网络支持

针对网络通信的不同层次,java提供的网络功能有四大类

1、InetAddress:用于标识网络上的硬件资源

2、Socket:使用TCP协议实现网络通信的Socket相关的类

3、Datagram:使用UDP协议,将数据保留在数据报中,通过网络进行通信

InetAddress类

1、InetAddress类用于标识网络上的硬件资源,表示互联网协议(IP)地址

public void inetAddressTest() throws Exception{
        //获取本机的InetAddressTest实例
        InetAddress localHost = InetAddress.getLocalHost();
        System.out.println("计算机名:"+localHost.getHostName());
        System.out.println("ip地址:"+localHost.getHostAddress());
        //获取字节数组形式的IP地址
        System.out.println(Arrays.toString(localHost.getAddress()));
        System.out.println(localHost);

        //根据机器名 获取InetAddress实例
        InetAddress byName = InetAddress.getByName("SONGPC");
        System.out.println(byName);

        //根据ip地址获取实例信息
        InetAddress address = InetAddress.getByName("192.168.43.52");
        System.out.println(address);
    }

Socket编程

TCP协议是面向连接、可靠的、有序的,以字节流的方式发送数据

基于TCP协议实现网络通信的类

客户端的Socket类

服务器端的ServerSocket类

Socket通讯的模型

image

Socket通信实现步骤

1.创建ServerSocket和Socket

2.打开连接到Socket的输入/输出流

3.按照协议对Socket进行读/写操作

4.关闭输入输出流、关闭Socket

服务器端:

1.创建ServerSocket对象,绑定监听端口

2.通过accept()方法监听客户端请求

3.连接通过后,通过输入流读取客户端发送的请求信息

4.通过输出流向客户端发送相应信息

5.关闭相关资源

//1.创建服务器端的Socket,指定绑定的端口,并监听此端口
        ServerSocket serverSocket=new  ServerSocket(8000);
        //2.调用accept()监听,等待客户端的连接  
        System.out.println("服务器:启动,等待客户端的连接***");
            //连接成功后创建socket
        Socket socket = serverSocket.accept();
        System.out.println("服务器:客户端已经连接成功!");
        //3.获取输入流,用来读取客户端发送信息
        InputStream is = socket.getInputStream();
        OutputStream outputStream = socket.getOutputStream();
        //包装成高效字符流
        BufferedReader br=new BufferedReader(new InputStreamReader(is));

        String  len="";
        while((len=br.readLine())!=null){
            System.out.println("服务端:"+len);
        }
        (用完一个关闭一个  不然回阻塞)
        socket.shutdownInput();

        //4.获取输出流相应客户端请求
        PrintWriter pw=new PrintWriter(outputStream);//包装成打印了
        pw.write("欢迎你。。。");
        pw.flush();

        socket.shutdownOutput();
        //关闭资源
        pw.close();
        outputStream.close();
        br.close();
        is.close();
        socket.close();
        serverSocket.close();

客户端:

1.创建Socket对象,指定需要连接的服务器的地址和端口号

2.连接建立后,通过输出流向服务器端发送请求信息

3.通过输入流获取服务器端响应的信息

4.关闭相关资源

//1.创建客户端Socket,指定服务器端的地址和端口号
        Socket socket=new Socket("localhost", 8000);
        //2.获取输出流,用来向服务器端发送信息
        OutputStream outputStream = socket.getOutputStream();
        PrintWriter pw=new PrintWriter(outputStream);
        //3.获取输入流获取服务器端的相应
        InputStream inputStream = socket.getInputStream();

        pw.write("用户名:admin;密码:123");
        pw.flush();
        //关闭输出流(用完一个关闭一个  不然回阻塞)
        socket.shutdownOutput();  

        BufferedReader br=new BufferedReader(new InputStreamReader(inputStream));
        String len="";
        while((len=br.readLine())!=null){
            System.out.println("客户端:"+len);
        }

        socket.shutdownInput();
        //关闭资源
        br.close();
        pw.close();
        outputStream.close();
        socket.close();

多线程服务器

应用多线程来实现服务器与多客户端之间的通信

基本步骤
1.服务器创建ServerSocket,循环调用accept()等待客户端连接

2.客户端创建一个socket并请求和服务器端连接

3.服务器端接受客户端请求,创建socket与该客户端建立专线连接

4.建立连接两个socket在一个单独的线程上对话

5.服务器端继续等待新的连接

服务器线程类ServerThread

public class ServerThread implements Runnable {

    private Socket socket;

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        while (true)
        {
            InputStream is = null;
            try {
                is = socket.getInputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
            OutputStream os = null;
            try {
                os = socket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
            DataInputStream dataInputStream = new DataInputStream(is);
            DataOutputStream dataOutputStream = new DataOutputStream(os);

            String string = null;
            try {
                string = dataInputStream.readUTF();

            } catch (IOException e) {
                e.printStackTrace();
            }
            System.out.println(string);

            try {
                dataOutputStream.writeUTF(string);
                if(string.equals("byebye"))
                {
                    System.out.println("客户端下线了,我也退出了");
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
}

服务器端

public class SimpleSocketServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(6666);
        System.out.println("服务器启动");

        while (true)
        {
            Socket socket = serverSocket.accept();//监听,等待客户端连接上来
            InetAddress inetAddress= socket.getInetAddress();//得到客户端的地址信息
            System.out.println("客户端:"+ inetAddress.getHostAddress() + "连接上来了");
            ServerThread serverThread = new ServerThread(socket);
            new Thread(serverThread).start();
        }

    }
}

客户端线程

public class ClientThread implements Runnable{

    private Socket socket;

    public ClientThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        while (true)
        {
            try {
                InputStream inputStream = socket.getInputStream();
                DataInputStream dataInputStream = new DataInputStream(inputStream);
                String response = dataInputStream.readUTF();//阻塞
                System.out.println("服务器回应:" + response);
                if(response.equals("byebye"))
                {
                    System.out.println("退出");
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

客户端

public class TcpClient {
//    public static boolean isDead = false;
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1",6666);

        ClientThread clientThread = new ClientThread(socket);
        Thread child = new Thread(clientThread);
        child.start();

        OutputStream os = socket.getOutputStream();
        DataOutputStream dataOutputStream = new DataOutputStream(os);

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入要发给服务器的信息:byebye 退出");
        while (scanner.hasNext())//阻塞在此处,等待用户在控制台的输入
        {
            String string = scanner.nextLine();
            dataOutputStream.writeUTF(string);
            if(string.equals("byebye"))
            {
                break;
            }
            System.out.println("请输入要发给服务器的信息:byebye 退出");
        }
    }
}

你可能感兴趣的:(Socket)