Java简单实现不同项目间的数据传输

简介:

        初步实现Java不同项目间的数据传输,后续会尝试对文本图片传输。

效果展示:

客户端输入:

服务端接收:

知识: 

服务端解析:

  • port 是 服务器监听的端口号(范围 0 - 65535,推荐使用 1024 以上的端口)
    • 但是注意不要设到已被占用的端口号了
    • Address already in use(设置到已经被占用的端口号报错)
int port = 8888;
  •  补充:查询端口号是否被占用:
  • PowerShellWin + X → 选择 Windows 终端(管理员))中输入:(把8080替换成想要查询的端口)
Get-NetTCPConnection -LocalPort 8080

端口被占用: 

端口没有被占用:

  •  创建一个 TCP 服务器套接字,并在指定的 port 端口上 监听客户端连接
    • 这个 serverSocket 会一直等待客户端的连接,直到调用 serverSocket.close(); 关闭它
ServerSocket serverSocket = new ServerSocket(port);
  •  等待客户端连接,当有客户端连接时,返回 Socket 对象。
    • 代码会阻塞(停在这里),直到有客户端连接
Socket socket = serverSocket.accept();
  •  获取客户端发送的输入流
InputStream inputStream = socket.getInputStream();
  •  使用 缓冲读取,按行读取客户端数据,提高效率
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

 客户端解析: 

  • 必须与服务器端口一致,否则无法连接
 int port = 8888;
  •  创建 Socket 客户端,连接到本机服务器(InetAddress.getLocalHost()
Socket socket = new Socket(InetAddress.getLocalHost(), port);
  •  获取输出流,用于向服务器发送数据
 OutputStream outputStream = socket.getOutputStream();
  • 添加 \n:确保服务器的 readLine() 可以正确读取。
  • 使用 UTF-8 编码,保证字符兼容性
socket.getOutputStream().write((message+"\n").getBytes(StandardCharsets.UTF_8));
  •  强制发送数据,避免缓冲区未满时服务器接收不到数据
 outputStream.flush();

代码:

客户端:

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws IOException {
        int port = 8888;
        try (Socket socket = new Socket(InetAddress.getLocalHost(), port);
             OutputStream outputStream = socket.getOutputStream();
             Scanner scanner = new Scanner(System.in);
        ) {
            System.out.println("链接到服务器,输入消息发送,输入“exit”退出");
            while (true) {
                String message = scanner.nextLine();
                if (message.equals("exit")) {
                    System.out.println("已断开连接");
                    break;
                }
                socket.getOutputStream().write((message+"\n").getBytes(StandardCharsets.UTF_8));
                outputStream.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

服务端:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

public class Main {
    public static void main(String[] args) {
        int port = 8888;
        System.out.println("等待客户端连接………………");
        try (ServerSocket serverSocket = new ServerSocket(port);) {
            Socket socket = serverSocket.accept();
            System.out.println("客户端连接: " + socket.getInetAddress());
            InputStream inputStream = socket.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
            String message;
            while ((message = reader.readLine()) != null) { // 按行读取
                System.out.println("收到消息: " + message);
            }
        } catch (IOException e) {
            System.out.println("客户端断开连接");
            e.printStackTrace();
        }
        System.out.println("客户端主动断开");
    }
}

问题注意:

无消息显示

服务端和客户端连接上了,但是在客户端输入信息,服务端接收不到,可以检查下面的两个代码:

 socket.getOutputStream().write((message+"\n").getBytes(StandardCharsets.UTF_8));
  • 这个message后面的“\n”一定要有,没有换行符 \n,会导致服务器 readLine() 无法读取完整消息,始终在等待,从而显示出没有消息接收到
 outputStream.flush();
  •  write() 只是写入缓冲区,没有 flush(),数据不会立即发送,可能导致服务器一直等不到数据。

 补充多线程:

效果展示:

代码 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class send implements Runnable{
    DatagramSocket datagramSocket=null;
    BufferedReader bufferedReader=null;
    private int portFrom;
    private int portTo;
    private String ip;
    public send(String ip,int portFrom,int portTo){
        this.portFrom=portFrom;
        this.portTo=portTo;
        this.ip = ip;
        try {
            this.datagramSocket = new DatagramSocket(portFrom);
            this.bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while (true){
            try {
                String string = bufferedReader.readLine();
                DatagramPacket datagramPacket = new DatagramPacket(string.getBytes(StandardCharsets.UTF_8), string.length(), new InetSocketAddress(this.ip, this.portTo));
                datagramPacket.getData();
                datagramSocket.send(datagramPacket);
                if( string.equals("bye")){
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

public class receive implements Runnable {
    DatagramSocket datagramSocket=null;
    private int port;
    public  receive(int port){
        this.port=port;
        try {
            this.datagramSocket = new DatagramSocket(this.port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {

        while(true){
            try {
                byte[] by=new byte[1024];
                DatagramPacket data = new DatagramPacket(by,0,by.length);
                this.datagramSocket.receive(data);
                int length = data.getLength();  // 获取实际接收到的字节数
                String string = new String(by, 0, length); // 正确的字符串转换
                /*String string = new String(by, 0, length, StandardCharsets.UTF_8);
                别这么写,这么写会导致,打印前面的字符串打印不出来!!!
                */
                System.out.println("receive: " + string);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }
}
public class peopleA {
    public static void main(String[] args) {
        new Thread(new send("localhost",8887,9999)).start();
        new Thread(new receive(7777)).start();
    }
}
public class peopleB {
    public static void main(String[] args) {
        new Thread(new send("localhost",8889,7777)).start();
        new Thread(new receive(9999)).start();
    }
}

注意点:

String string = new String(by, 0, length, StandardCharsets.UTF_8);别这么写,这么写会导致,打印前面的字符串打印不出来!!!回头再探究.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值