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(),来断开客户端的输出流,然后服务器继续执行第五步反馈客户端。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老板来碗小面加蛋~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值