java TCP编程

1、软件架构设计

CS架构.服务器客户端程序 优势:把一部分的计算留在客户端进行,缓解服务器压力。 劣势:如果游戏或者软件进行升级,客户端必须手动更新。 客户端:可以给服务器发送数据的软件,可以接收服务器发送过来的数据。 服务端:负责接收客户端发送过来的数据,处理数据,给客户端以响应。

BS架构.浏览器服务器架构 优势:维护成本比较低。 劣势:没办法在客户端做大量的计算。

2、Socket

Socket抽象层,相当于将传输层、网络层、链路层封装起来了,通过很简单的对象调用以及参数赋予即可实现网络通信。 极大的方便了程序的开发使用。

因为通过对计算机网络概述的了解,会发现连接只需要IP、端口号即可,其它的东西都是一成不变的。java TCP编程_第1张图片

3、客户端服务端连接

通过ServerSocket来创建服务端对象,规定使用的端口号即可。 通过Socket对象来连接服务端,需要参数ip和端口号即可。

public class Server {
    public static void main(String[] args) throws IOException {
        // 1.创建服务器端对象
        ServerSocket ss = new ServerSocket(9999); // 服务端使用端口号 9999
        System.out.println("服务端启动成功,等待连接");
       
        // 2.等待客户端连接
        ss.accept(); // 阻塞状态,在客户端连接之前都是阻塞态,连接成功之后会继续
        System.out.println("客户端连接成功!!!");
    }
}
​
public class Client {
    public static void main(String[] args) throws IOException {
        // 1. 创建Socket对象
        Socket socket = new Socket("127.0.0.1", 9999); // 连接服务端,规定IP和端口号
        System.out.println("客户端连接服务器成功!!");
    }
}

4、客户端服务端数据传输

Socket类中留的有数据传输通道,就是IO流,但仅仅是字节流,读取文本的话为了方便可以转为字符流去使用。

可以通过Socket来获取数据传输的通道,s.getInputStream(),来获取读取通道,s.getOutputStream()来获取写入通道,转为字符流之后套上BufferedReader或者BufferedWriter来使用更加的方便

而服务端中ss.accept()会等待客户端连接,连接之后返回值为Socket类,通过这个来获取socket就行。

以下程序实现的是一来一回的交互。

  • 注意事项:除非保证写入通道不再使用,否则不要关。

public class Server {
    public static void main(String[] args) throws IOException {
        // 1.创建服务器端对象
        ServerSocket ss = new ServerSocket(9999);
        System.out.println("服务端启动成功,等待连接");
​
        // 2.等待客户端连接
        Socket s = ss.accept(); // 阻塞
        System.out.println("客户端连接成功!!!");
        Scanner sc = new Scanner(System.in);
        while(true){
            // 3.读取客户端传来的数据
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            System.out.println("从客户端读取的数据为:" + br.readLine());
            // 4.给客户端发送一条数据
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            bw.write(sc.nextLine()); // 从运行框读入字符串发送给客户端
            bw.newLine(); // 为了客户端方便使用Buffered,最好加上一个换行。
            bw.flush(); // 必须要刷新,因为传输比较麻烦,不刷新可能会丢失数据。
        }
    }
}
public class Client {
    public static void main(String[] args) throws IOException {
        // 1. 创建Socket对象
        Socket socket = new Socket("127.0.0.1", 9999);
        System.out.println("客户端连接服务器成功!!");
        Scanner sc =  new Scanner(System.in);
        while(true) {
            // 2.从客户端发送数据给服务器
            OutputStream os = socket.getOutputStream();
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
            bw.write(sc.nextLine());
            bw.newLine();
            bw.flush();
            // 3.接收从服务端发来的信息
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            System.out.println("从服务器接收的数据为:" + br.readLine());
        }
    }
}

5、作业

  • 要求:实现一个多人聊天室。

服务端

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(8989);
        System.out.println("服务器已经启动,等待连接中。");
        List sockets = new ArrayList(); // 用来存放所有连接服务器的用户的socket
        while(true){ // 保证所有想连接服务器的用户都可以正常连接
            Socket s = ss.accept();
            System.out.println("---加入了一个客户端---");
            sockets.add(s); // 加入用户socket列表
            new ServerMsgThread(s, sockets).start(); // 实现一个线程,用来接收当前socket的消息,并且发给其它所有socket,需要传参,本身socket以及socket列表,然后启动线程。
        }
    }
}

客户端

public class Client {
    public static void main(String[] args) throws IOException {
        // 1. 连接服务器
        Socket s = new Socket("127.0.0.1", 8989);
        System.out.println("连接到服务器了,可以开始聊天了。");
        // 2.不停的发送消息
        new SendMsgThread(s).start(); // 实现一个不停发送消息的进程
        // 3.不停的接收消息
        new ReceMsgThread(s).start(); // 实现一个不停接收消息的进程
    }
}

你可能感兴趣的:(java,tcp/ip,开发语言)