Java核心基础——08 - Java网络编程

Java网络编程



一、网络编程

1.1 网络通信

计算机之间的信息交互是通过服务器作为媒介的

数据传输离不开IO流

网络通信协议:计算机通信必须遵守的通信规则,不遵守则不能进行通信。通信协议对数据的传输格式、传输速率、传输步骤等做了同意规定。

TCP/IP协议:定义了计算机如何连入Internet网,以及数据之间传输的标准

通信协议:

TCP:面向连接,安全、可靠、数据大小没有限制

三次握手

1.客户端给服务器发送连接请求,等待服务器确认

2.服务器回复一个响应,通知客户端收到了请求

3.客户端再次向服务器发送信息,确认连接

UDP:面向无连接,不安全、不可靠、数据大小有限制

网络三要素

IP地址: 本机IP地址 127.0.0.1 、localhost

端口号: 一般四位

协议:TCP/UDP

1.2 TPC通信程序

1.2.1 两端通信时步骤

1.服务器程序,需要先启动,等待客户端的连接

2.客户端主动连接服务器,连接成功才能通信。服务器不能主动连接客户端

使用两个类实现TCP通信

1.客户端:java.net.Socket

//两个参数:1.服务器的ip地址;2.程序的端口号
public Socket(String host, int port) throws UnknownHostException, IOException{
	this(host != null ? new InetSocketAddress(host, port) :
	new InetSocketAddress(InetAddress.getByName(null), port),
	(SocketAddress) null, true);
}

2.服务器:java.net.ServerSocket

//参数:指定程序的端口号,等待客户端的连接
public ServerSocket(int port) throws IOException {
     this(port, 50, null);
}

1.2.2 代码实现

  1. 客户端与服务器通信
//客户端
public class Demo03Socket {
    public static void main(String[] args) throws IOException {
        //创建客户端对象
        Socket socket = new Socket("127.0.0.1", 9999);

        OutputStream out = socket.getOutputStream();
        InputStream in = socket.getInputStream();
        Scanner scanner = new Scanner(System.in);
        while (true) {
            //发送消息
            String msg = scanner.next();
            out.write(msg.getBytes());
            //接受消息
            byte[] bytes = new byte[1024];
            int len = in.read(bytes);
            System.out.println(new String(bytes));
        }
//        in.close();
//        out.close();
//        socket.close();
    }
}

//服务器
public class Demo03ServerSocket {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(9999);
        //等待客户端的连接,返回值是客户端对象
        Socket accept = serverSocket.accept();
        InputStream in = accept.getInputStream();
        OutputStream out = accept.getOutputStream();
        Scanner scanner = new Scanner(System.in);
        System.out.println("客户端连接");
        while (true) {
            //接受消息
            byte[] b = new byte[1024];
//        int len;
            in.read(b);
            System.out.println(new String(b));
            //发送消息
            String message = scanner.next();
            out.write(message.getBytes());

        }
//        out.close();
//        in.close();
//        serverSocket.close();
    }
}
  1. 多个客户端与服务器通信(客户端代码没变化,只需要创建多个类就行)
//服务器
public class Demo04ServerSocket {
    public static void main(String[] args) throws IOException {
        //创建服务器
        ServerSocket serverSocket = new ServerSocket(9999);
        while (true) {
            Socket accept = serverSocket.accept();
            System.out.println("客户端连接");
            /*
            这为什么要用线程呢
            因为线程会从新开辟一个运行路线,main方法的程序执行到这就会跳过,然后又会回到上面的循环
            如果没有线程,就会一直陷入在下面的无限循环对话中
             */
            new Thread(() -> {
                try {
                //等待客户端的连接,返回值是客户端对象,具有阻塞的效果
                    InputStream in = accept.getInputStream();
                    OutputStream out = accept.getOutputStream();
                    Scanner scanner = new Scanner(System.in);
                    //接受消息
                    byte[] b = new byte[1024];
//        int len;
                    while (true) {
                        in.read(b);
                        System.out.println(new String(b));
                        //发送消息
                        String message = scanner.next();
                        out.write(message.getBytes());
                    }
                } catch (Exception e) {

                }
            }).start();
        }
//        out.close();
//        in.close();
//        serverSocket.close();
    }
}

注意事项

  1. 线程的使用。在服务器端使用多线程的时候需要创建一个死循环,然后利用服务器创建客户端对象的阻塞来控制循环的执行次数。所以客户端对象的创建放在循环的里面。线程要放在创建客户端对象的代码下面,这样将服务器与客户端对象的通信代码脱离了主线程,也不会影响到其他客户端的创建。
  2. 客户端输出流的使用。当服务器接收从客户端传来的资源时(反之也一样),使用到了while循环,这时只有当客户端的输出流关闭了,服务器的whhile循环才不会阻塞,否则就会默认客户端还会传来资源,然后处于一直等待的状态。所以要记得客户端使用输出流后要关闭。关闭的方法有三:
    1. 直接关闭客户端对象:client.close();
    2. 关闭输出流:out.close();
    3. showdownOutput()方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值