Java 网络编程 01 —— Socket TCP通信

系列文章目录

Java 网络编程 01 —— Socket TCP通信
Java 网络编程 02 —— Socket UDP通信
Java 网络编程 03 —— URL下载资源



Java Socket TCP通信

TCP实现聊天

服务器:

  1. 建立服务器的端口。利用ServerSocket类。
  2. 等待用户的连接 。利用serversocket的accept方法返回一个客户端的socket。
  3. 接受用户消息。利用返回的客户端的socket获取输入流。
package lessen01;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

//服务器
public class TCPServerDemo01 {
    
    
    public static void main(String[] args) {
    
    
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        int count = 1;
        try {
    
    
            //1. 有一个地址和端口号
            serverSocket = new ServerSocket(9999);//自定义一个端口
            //实现一直传输,直到客户端输入end
            while(true){
    
    
                //2. 等待客户端连接
                socket = serverSocket.accept();//获取客户端的socket
                //3. 读取客户端的消息
                is = socket.getInputStream();//获取客户端socket的输入流

                baos = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int len;
                while((len = is.read(buffer))!=-1){
    
    
                    baos.write(buffer, 0, len);
                }
                System.out.println(baos.toString()+"。第"+(count++)+"次连接。");
                if(baos.toString().equals("end"))
                    break;
            }
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            //关闭所有流
            if (baos != null) {
    
    
                try {
    
    
                    baos.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if (is != null) {
    
    
                try {
    
    
                    is.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
            if(socket != null) {
    
    
                try {
    
    
                    socket.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }

            if (serverSocket != null) {
    
    
                try {
    
    
                    serverSocket.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }

        }


    }
}

客户端:

  1. 利用InetAddress设置好服务器IP地址。
  2. 在服务器已建立好的前提下,连接服务器。利用Socket类连接服务器。
  3. 发送消息。利用Socket类获取输出流。
package lessen01;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

//客户端
public class TCPClientDemo01 {
    
    
    public static void main(String[] args) {
    
    
        Socket socket = null;
        OutputStream os = null;
        Scanner scanner = new Scanner(System.in);
        String string = null;
        //实现一直传输,直到键盘输入end
        while(true){
    
    
            try {
    
    
                //1. 知道服务器地址,端口号
                InetAddress serverIP = InetAddress.getByName("127.0.0.1");
                int port = 9999;
                //2. 创建一个Socket连接
                socket = new Socket(serverIP, port);
                //3. 发送消息 IO流
                os = socket.getOutputStream();

                string = scanner.nextLine();
                os.write(string.getBytes());
            } catch (Exception 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(string.equals("end"))
                break;
        }
    }

}

TCP实现文件上传

客户端:

  1. 创建Socket连接。
  2. 从Socket获取输出流。
  3. 创建文件输入流。
  4. 从文件输入流中读取文件,并输出到服务器。
  5. 通知服务器,已发送完毕。
  6. 确定服务器接受完毕。
  7. 关闭资源。
package lessen01;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

public class TCPClientDemo02 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //1. 创建一个Socket连接
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"), 9999);
        //2. 从Socket获取输出流
        OutputStream os = socket.getOutputStream();
        //3. 创建文件输入流
        FileInputStream fis = new FileInputStream(new File("zhang.png"));
        //4. 从文件输入流中读取文件,并输出到服务器
        byte[] buffer = new byte[1024];
        int len;
        while((len = fis.read(buffer))!= -1){
    
    
            os.write(buffer, 0, len);//将字节数组中内容全部输出
        }

        //5. 通知服务器,已发送完毕。这里如果不通知,则程序会陷入阻塞。下面解释原因。
        socket.shutdownOutput();

        //6. 确定服务器接受完毕
        InputStream is = socket.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer2 = new byte[1024];
        int len2;
        while((len2 = is.read(buffer2))!=-1){
    
    
            baos.write(buffer2, 0, len2);
        }
        System.out.println(baos.toString());

        //7. 关闭资源
        baos.close();
        is.close();
        fis.close();
        os.close();
        socket.close();
    }
}

服务器:

  1. 创建一个ServerSocket连接。
  2. 监听客户端连接。
  3. 读取客户端数据。
  4. 创建文件输出流。
  5. 通知客户端,已接受完毕。
  6. 关闭资源。
package lessen01;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServerDemo02 {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //1.  创建一个ServerSocket连接
        ServerSocket serverSocket = new ServerSocket(9999);
        //2. 监听客户端连接
        Socket socket = serverSocket.accept();//阻塞式监听,会一直等待连接
        //3. 读取客户端数据
        InputStream is = socket.getInputStream();
        //4. 创建文件输出流
        FileOutputStream fos = new FileOutputStream(new File("./receive.png"));
        byte[] buffer = new byte[1024];
        int len;
        while((len=is.read(buffer))!=-1){
    
    
            fos.write(buffer, 0, len);
        }

        //5. 通知客户端,已接受完毕
        OutputStream os = socket.getOutputStream();
        os.write("服务器已接受数据完毕".getBytes());


        //6. 关闭资源
        os.close();
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}

​    上述客户端部分第5步, socket.shutdownOutput();是告诉服务器客户端数据已经发送完毕,并关闭输出流【此时Socket仍然连接,只是输出流关闭了】。
    如果省略这一步,后续客户端会一直卡在确定服务器接受数据完毕的read()位置,等待服务器回复。而服务器因为不知道客户端是否发送完毕,也会一直卡在第4步的read()位置。
    之前TCP实现聊天是因为调用close()方法,关闭了输入输出流,服务器客户端双知道,而这次在close()前面还有一次通知操作,因此需手动调用shutdownOutput(),来断开客户端的输出流,然后服务器继续执行第五步反馈客户端。

猜你喜欢

转载自blog.csdn.net/qq_39763246/article/details/112843472