美文网首页Java
java学习笔记#8-Java Socket

java学习笔记#8-Java Socket

作者: edwin1993 | 来源:发表于2017-08-30 10:10 被阅读0次

网络基础

通信必备条件.png
  • 端口:区别是电脑上的哪个进程发出的通信请求(0 ~ 65535,其中1~1023系统保留)
    http:80 ftp:21 telnet:23
  • 协议:通信过程所使用的语言(TCP/IP)
  • IP地址:互联网中的唯一标识

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

JAVA中的网络支持
针对网络通信的不同层次,java提供的网络功能分为四大类

  • InetAddress:用于标识网络上的硬件资源,类IP地址。
  • URL:统一资源定位符 通过URL可以直接读取和写入网络上的数据。
  • Sockets:使用TCP协议实现网络通信的Socket相关的类。
  • Datagram:使用UDP协议,将数据保存在数据报中,通过网络进行通讯。

InetAddress类

无构造方法,无法通过new的方法创造对象。有很多静态方法,可以返回该类。

public void useInetAddress(){

        try {
            //        获取本机的InetAddress
            InetAddress inetAddress = InetAddress.getLocalHost();
            System.out.println("计算机名" + inetAddress.getHostName());
            System.out.println("计算机IP" + inetAddress.getHostAddress());
            System.out.println(inetAddress);

//            其它获取inetAddress的方式
//            InetAddress inetAddress2 = InetAddress.getByName("Edwin");
//            InetAddress inetAddress3 = InetAddress.getByName("1.1.1.10");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

    }

URL类

public void useURL(){
        try {
//            创建URL实例
            URL immoc = new URL("http://www.imooc.com");
            URL url = new URL(immoc,"/index.html?username=tom#test");

            System.out.println("协议:"+ url.getProtocol());
            System.out.println("Host:"+ url.getHost());
//            如果为指定端口号,则为-1
            System.out.println("Port:" + url.getPort() );
            System.out.println("filePath:" + url.getPath());
            System.out.println("fileName:" + url.getFile());
            System.out.println("相对路径:"+ url.getRef());
            System.out.println("查询字符串:"+ url.getQuery());




            URL baidu = new URL("http://www.baidu.com");
//            通过URL对象的openStream方法可以获取指定资源的输入流
            InputStream inputStream = baidu.openStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
//            添加缓冲 提高效率
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String data = bufferedReader.readLine();
            while (data!=null){
                System.out.println(data);
                data = bufferedReader.readLine();
            }
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Socket-TCP编程简介

  • 基于TCP协议实现网络通讯的类
    服务端的Socket类
    客户端的ServerSocket类
Socket通信模型.png

实现步骤:
创建serversocket 和socket
打开连接到socket的输入/输出流
按照协议读写
关闭输入输出流

public class ServerModel {
    public static void main(String args[]){
        try {
//       创建服务器端的socket,绑定指定的端口并监听
            ServerSocket serverSocket = new ServerSocket(8888);
//            调用accept监听
            System.out.println("等待客户端链接");
            Socket socket = serverSocket.accept();
//            获取客户端的信息
            InputStream is = socket.getInputStream();
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader bufferedReader = new BufferedReader(isr);
            String info = null;
            while ((info = bufferedReader.readLine())!=null){
                System.out.println("client info : " + info);
            }
            socket.shutdownInput();

            OutputStream outputStream = socket.getOutputStream();
            PrintWriter printWriter = new PrintWriter(outputStream);
            printWriter.write("welcome");
            printWriter.flush();

//           关闭资源
            printWriter.close();
            outputStream.close();

            bufferedReader.close();
            isr.close();
            is.close();
            socket.close();
            serverSocket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

public class ClientModel {
    public static void main(String args[]){
//        创建客户端的socket,指定服务器端的地址和端口
        try {
            Socket socket = new Socket("localHost",8888);
//            获取输出流发送登陆信息
            OutputStream os = socket.getOutputStream();
            PrintWriter pw = new PrintWriter(os);
            pw.write("userName:edwin;key:123");
            pw.flush();

            socket.shutdownOutput();
//            获取输入流来获取服务器端的响应
            InputStream inputStream = socket.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String info = null;
            while ((info = bufferedReader.readLine())!= null){
                System.out.println("server said:"+info);
            }
//            关闭资源
            bufferedReader.close();
            inputStream.close();

            pw.close();
            os.close();
            socket.close();

        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


运行结果.png 运行结果.png

为上面所演示的程序添加多线程来实现多客户端的功能
继承线程类

public class ServerThread extends Thread {

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

//    线程执行的操作,响应客户端的请求
    public void run(){
        InputStream is = null;
        InputStreamReader isr = null;
        BufferedReader bufferedReader = null;
        OutputStream outputStream = null;
        PrintWriter printWriter = null;
        try {
 //            获取客户端的信息
            is = socket.getInputStream();
            isr = new InputStreamReader(is);
            bufferedReader = new BufferedReader(isr);
            String info = null;
            while ((info = bufferedReader.readLine())!=null){
                System.out.println("client info : " + info);
            }
            socket.shutdownInput();
            outputStream = socket.getOutputStream();
            printWriter = new PrintWriter(outputStream);
            printWriter.write("welcome");
            printWriter.flush();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //           关闭资源
            try{
                printWriter.close();
                outputStream.close();
                bufferedReader.close();
                isr.close();
                is.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}

在服务器端启动循环监听

Socket socket = null;
            int count = 0;
//            循环监听
            while (true){
                socket = serverSocket.accept();
//                创建线程
                ServerThread serverThread = new ServerThread(socket);
                serverThread.run();
                System.out.println(++count);
            }
运行结果.png

Socket-UDP编程简介

UDP无连接无序,数据封装为数据报的形式(datagram)

  • 需要用到的类:
    DatagramPacket:表示数据报包
    DatagramSocket:表示端到端通信的类
public class UDPServer {
    public static void main(String args[]){
        try {
//            创建服务器端的DatagramSocket,指定端口
            DatagramSocket socket = new DatagramSocket(8800);
//            创建数据报文,由于接受服务端的数据
            byte[] data = new byte[1024];
            DatagramPacket packet = new DatagramPacket(data,data.length);
//            接收数据
            System.out.println("服务器端启动...");
            socket.receive(packet);//此方法在接收到数据之前会一直阻塞
//            读取数据
            System.out.println("从客户端得到的数据为:"+ new String(data));
//            向客户端发送响应
//            定义客户端的地址,端口等
            InetAddress address = packet.getAddress();
            int port = packet.getPort();
            byte[] reMessage = "welcome".getBytes();
//            创建数据报
            DatagramPacket rePacket = new DatagramPacket(reMessage,reMessage.length,address,port);
//            响应
            socket.send(rePacket);
            socket.close();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


public class UDPClient {
    public static void main(String args[]){
        try {
//            定义服务器地址
            InetAddress address =InetAddress.getByName("localHost");
            int port = 8800;
            byte[] data = "此为服务端数据内容".getBytes();
//            创建数据报
            DatagramPacket packet = new DatagramPacket(data,data.length,address,port);
//            创建socket
            DatagramSocket socket = new DatagramSocket();
//            发送
            socket.send(packet);
//            接收响应
            byte[] reMessage = new byte[1024];
            DatagramPacket repacket = new DatagramPacket(reMessage,reMessage.length);
            socket.receive(repacket);
            System.out.println(new String(reMessage));
            socket.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
运行结果.png

补充内容

在TCP的示例中使用了多线程来完成持续监听来模拟多个客户端的访问,我们可以通过设计线程的优先级来调整程序的运行情况

...
serverThread.setPriority(4);//范围[1,10],默认:5
...

输出流关闭的过程中会一起关闭socket,所以不单独进行关闭。传输可以以对象的形式进行,只需要使用ObjectOutputStream。

相关文章

  • java学习笔记#8-Java Socket

    网络基础 端口:区别是电脑上的哪个进程发出的通信请求(0 ~ 65535,其中1~1023系统保留)http:80...

  • 《Netty实战》读书笔记01——第一章

    第 1 章 笔记 Java 网络编程 早期Java的网络编程,需要学习很多C语言套接字(Socket)的知识,但...

  • 网络编程

    python学习笔记-网络编程 socket编程: socket()函数:socket.socket([famil...

  • #Socket回顾学习笔记

    Socket学习笔记 Socket基础知识 背景 Socket概念 Socket 又称"套接字",是系统提供的用于...

  • iOS#GCDAsyncSocket使用

    背景 最近在开发使用Socket,重新复习了socket基本知识,文章如下: #Socket回顾学习笔记UDP G...

  • java socket 线程池echo服务器

    java socket系列文章java socket 单线程echo服务器java socket 多线程ech...

  • java socket 多线程echo服务器

    java socket系列文章java socket 单线程echo服务器java socket 多线程ech...

  • java socket 单线程echo服务器

    java socket系列文章java socket 单线程echo服务器java socket 多线程ech...

  • 相关文章

    我的笔记核心理论基础、Socket通信原理、RPC远过程调用协议、Dubbo博客 java注解-01、java注解...

  • java socket学习

    Socket(套接字) socket是处在应用层之下、传输层之上的接口层,它是操作系统提供用户访问网络的接口,借助...

网友评论

    本文标题:java学习笔记#8-Java Socket

    本文链接:https://www.haomeiwen.com/subject/xetgdxtx.html