socket网络编程之实现聊天室

「这是我参与2022首次更文挑战的第20天,活动详情查看:2022首次更文挑战

前言

这个也是一个简单的小dome。 那么对接下来的几天差不多一个礼拜回校,那么安排如下,主要是针对前面的java内容,因为前半段时间都在刷Letcode,玩虚幻四,以及python,pytorch部分的内容,那么毕竟主力还是java这方面的内容。所以接下来的任务是:

1.java反射,注解
2.多线程,多进程,同步,线程进程池,几大锁
3.数据库,jdbc druid jdbctemplate
4.算法思想加 15<x<=20蓝桥杯题目
5.maven操作,spring项目,springboot项目重新熟悉一遍
复制代码

前面一开始玩java就是从框架开始的一开始的,毕竟先前的python基本上把很多思想都学了一遍,对我来说就是换几个API,但是现在毕竟还是要以java为主力,包括现在在实验室也基本上除了用python写点算法,都是用java在搞事情,所以很多内容不得不重新熟悉补充起来。用框架跳的比较快,但是方向感非常好,比如今天补充了Tomcat servlet的一些使用包括一些jsp也是慢慢地对原来一开始玩的 ssm 想要进行一点深入的探究。不过我个人说话大实话,我也很庆幸没有一开始就学servlet,因为这个真的和从python过来的路线没什么太大区别,真的就是换了几个api,并且比python麻烦了那么一点点,如果要我建议学习web,那就是数据库打通,了解基本网络协议,基本设计模式,然后上手 spring ,springboot 然后基于boot 学习mybatis,mvc,包括后面的springcloud 学习spring为了更好使用springboot,然后都基于springboot 学习,servlet其实适合作为一个了解,后面学习源码学习的也是它的设计思想,设计模式。不学servlet 学习java web从SSM开始没有任何影响,除非你想探究底层实现,那你应该关注的也不是servlet而是计算机网络,socket之类的。把另一个“古老”的框架当做另一个框架的“底层”是非常可笑的事情,了解servlet的工作流程只是对现在的框架的工作模式会有更加深刻的理解,例如,为什么要封装Tomcat,模板语法原来是怎么来的,它的实现过程是怎么样的,这些其实已经够了。

Java流

在进行网络编程之前,我们一定要搞清楚,流这玩意对于Java来说是多么重要。我们可以通过流来完成文件的存储,读取,同时也通过流来对网络数据进行传输。在Java当中没有指针的概念,我们知道在C语言当中它把所有的抽象的概念例如屏幕,键盘都看作了文件,对应就是指针(例如屏幕stdout标准输出,stdin标准输入)那么在Java当中流也充当了类似指针的作用。

socket定义

何为socket,这玩意其实就我们的网络驱动程序开放的接口,我们通过它来完成我们网络的连接数据的发生。当然在不同的计算机语言当中其具体的操作有细微的区别,例如在Java当中我们可以直接使用字符流来进行中文的直接传输,但是在python当中在传输时都必须先将数据转换为bytes,之后在对其进行解码。 一,Java 在这里插入图片描述 二,python

    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    id = socket.gethostbyname(socket.gethostname()).split(":")[0]
    s.connect((id,8089))
    s.send('你好!'.encode('utf8'))
    print("数据发送完成")
    tes=s.recv(1024)
    print(tes.decode('utf8'))
    s.close()

复制代码

Java socket的使用

socket的流程图 一.发送数据的过程 在这里插入图片描述 二.接受数据的过程 在这里插入图片描述 Java中socket需要使用到的基本方法

我们在这里需要先了解到三个方法

  1. getInputStream()这玩意可以得到在网络当中传输的数据流(发送至当前设备的数据,这个时直接在网卡那边获取的)

  2. getOutputStream()这玩意是用来发送的流,将你想要发送的数据发送出去

  3. accept()这玩意是服务端进行接听是否有数据传入的,是否有连接,返回类型为socket

此外在客户端使用的是socket在服务端使用的是servicesocket

服务端代码 这里的话方便做参考就写两个吧,一个是Java的一个是python的 一java


import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;


public class EchoServiceDome {

public static void main(String[] args) {
    try {

        ServerSocket server = new ServerSocket(6666);
        System.out.println("服务器已启动正在等待客户端连接");
        Socket socket = server.accept();//和python一样时阻塞的 
        System.out.println("客户端连接成功:"+server.getInetAddress().getHostAddress());
        //socke.getInputStream()通过流进行数据传递所以我们那啥可以用这个获取接受
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        //读取那个网络的数据
        String info = br.readLine();
        System.out.println(info);

        //写入数据,返回给客户端
        PrintStream ps = new PrintStream(new BufferedOutputStream(socket.getOutputStream()));
        ps.println("echo:"+info);
        ps.flush();
        ps.close();
        br.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
}

复制代码

二python

    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    id = socket.gethostbyname(socket.gethostname()).split(":")[0]
    s.connect((id,8089))
    s.send('hello'.encode('utf8'))
    print("数据发送完成")
    tes=s.recv(1024)
    print(tes.decode('utf8'))
    s.close()

复制代码

客户端

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class EchoClientDome {
    public static void main(String[] args) {
        
        //我们时直接通过字符流来传输的,所以不用和python一样那个是统一转换为了bytes之后我们在解码
        //主要是有用python做了很多封装本质上也是类似的
        try {
            //连接服务器
            Socket  socket = new Socket("localhost",6666);
            PrintStream ps = new PrintStream(new BufferedOutputStream(socket.getOutputStream()));//发送给服务器
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));//接手服务器的反馈

            ps.println("你好");
            ps.flush();
            //读取,在服务器未发送数据前会处于堵塞状态,也就是会等待服务器相应。
            String info = br.readLine();
            System.out.println(info);
            ps.close();
            br.close();

        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

复制代码

二python

    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    id = socket.gethostbyname(socket.gethostname()).split(":")[0]
    s.bind((id,8089))
    print("TCP服务器开启")
    s.listen(128)
    data,ip_where=s.accept()
    print(data.recv(1024).decode('utf8'))
    data.send('world'.encode('utf8'))

复制代码

多客户端请求处理

具体的流程如下图 在这里插入图片描述 代码如下:

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class MutilateServiceDome {
    public static void main(String[] args) {
        ExecutorService es = Executors.newFixedThreadPool(4);
        try {
            ServerSocket server = new ServerSocket(6666);
            System.out.println("服务器已开启......");
            while(true){
                Socket s = server.accept();
                System.out.println("Host:"+s.getInetAddress().getHostAddress()+"请求访问!");
                es.execute(new UserDoThread(s));
            }

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
}

class UserDoThread implements Runnable{
    private Socket s;
    private BufferedReader br;
    private PrintStream ps;
    public UserDoThread(Socket s){
        this.s = s;
    }
    public void run(){
        try {
            br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            ps = new PrintStream(new BufferedOutputStream(s.getOutputStream()));
            String info = br.readLine();
            System.out.println(info+"---来自:"+s.getInetAddress().getHostAddress());
            ps.println("echo:"+info);
            ps.flush();
            ps.close();
            br.close();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            ps.flush();
            ps.close();
            try {
                br.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
    }
}
复制代码

猜你喜欢

转载自juejin.im/post/7062686156223152159