java socket编程

Socket 常用分为以下两种

ServerSocket //服务端
Socket//客户端

简单连接1(服务端):

//创建一个Socket 监听端口为80
 ServerSocket serverSocket = new ServerSocket(80);
//获取服务端的Socket
 Socket accept = serverSocket.accept();
//创建一个线程专门处理Socket请求
new TestThread(accept).start();

//--------------------TestThread

    public static class TestThread extends Thread{

        //获取当前服务器Socket
        private Socket mSocket;

        public TestThread(Socket mSocket){
            this.mSocket = mSocket;
        }

        @Override
        public void run() {

            try {
            //创建一个字符串读取流
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
                
                String msg = null;
            //如果读取到的东西不为 null 并且不能为空(这是客户端发送过来的消息)
                while((msg = bufferedReader.readLine()) != null && !(msg.isEmpty())){
                    //打印输出看一下
                    System.out.println(msg);
                }
                
                
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }



客户端

//监听 本地 127.0.0.1 端口为80
 Socket socket = new Socket("127.0.0.1", 80);
//获取一个打印输出流
 PrintWriter printWriter =  new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));

 printWriter.println("我给服务端发送了一个消息");
//刷新流
 printWriter.flush();
//关闭流
 printWriter.close();

效果图

image.png

这个是通过ServletSocket监听一个端口 通过Socket来请求,但是这样你感觉没啥用啊,只能发送一次,链接就被关闭了

没事咋们再来点高端的

简单连接2

服务端不变,来看下客户端

 Socket socket = new Socket("127.0.0.1", 80);
   
        new Thread(new Runnable() {
            @Override
            public void run() {

                PrintWriter printWriter = null;
                try {
                    //获取打印输出流
                    printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                //从键盘获取输入流
                Scanner scanner = new Scanner(System.in);

                while(true){

                    String s = scanner.nextLine();
                     //发送给服务端
                    printWriter.println(s);
                    printWriter.flush();
                }


            }
        }).start();

效果图

image.png

简单连接 3

你也可以这样,给服务端(Servlet发送时间 1秒发一次 服务端不变)

 Socket socket = new Socket("127.0.0.1", 80);
   

        new Thread(new Runnable() {
            @Override
            public void run() {

                PrintWriter printWriter = null;
                try {
                    printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
                } catch (IOException e) {
                    e.printStackTrace();
                }

                Date date = new Date();

                SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                while(true) {

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // String s = scanner.nextLine();

                    long l = System.currentTimeMillis();


                    date.setTime(l);
                    String format = s.format(date);


                    printWriter.println(format);
                    printWriter.flush();
                }

            }
        }).start();

效果图

image.png

简单连接 4 (双向通讯)

就是说你收到了服务端的消息,然后你给服务端发送消息,说你收到了

服务端 需要更改一些东西

//创建一个Socket 监听端口为80
 ServerSocket serverSocket = new ServerSocket(80);
//获取服务端的Socket
 Socket accept = serverSocket.accept();
//创建一个线程专门处理Socket请求
new TestThread(accept).start();

//--------------------TestThread

    public static class TestThread extends Thread{

        //获取当前服务器Socket
        private Socket mSocket;

        public TestThread(Socket mSocket){
            this.mSocket = mSocket;
        }

        @Override
        public void run() {

            try {
            //创建一个字符串读取流
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
            //创建一个打印流,传给客户端
                 PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(mSocket.getOutputStream()),true);
                String msg = null;
            //如果读取到的东西不为 null 并且不能为空(这是客户端发送过来的消息)
                while((msg = bufferedReader.readLine()) != null && !(msg.isEmpty())){
                    //打印输出看一下
                    System.out.println(msg);
                    //发送给客户端
                   printWriter.println("服务端收到消息:" + msg);
                }
                
                
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


客户端

 Socket socket = new Socket("127.0.0.1", 80);
     

 
          //多加了一行这个,监听服务端发送过来的消息
          new TestThread(socket).start();


        new Thread(new Runnable() {
            @Override
            public void run() {

                PrintWriter printWriter = null;
                try {
                    printWriter = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
                } catch (IOException e) {
                    e.printStackTrace();
                }

       

                Date date = new Date();

                SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                while(true) {

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // String s = scanner.nextLine();

                    long l = System.currentTimeMillis();


                    date.setTime(l);
                    String format = s.format(date);


                    printWriter.println(format);
                    printWriter.flush();
                }

            }
        }).start();

//---------------------------------TestThread

 public static class TestThread extends Thread {

        private Socket mSocket;

        public TestThread(Socket mSocket) {

            this.mSocket = mSocket;

        }

        @Override
        public void run() {

//基本和服务端写的差不多
            try {
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));

                PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(mSocket.getOutputStream()));



                String msg = null;
                while ((msg = bufferedReader.readLine()) != null) {

                  //监听服务端发送过来的消息
                    System.out.println(msg);

                }

    
                printWriter.flush();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

效果图

image.png

服务端和客户端都可以双向通讯

服务端 -> 客户端(接收到消息 发送给服务端通知我收到了)->服务端(知道客户端收到消息了 通知给客户端新的东西)->客户端(好的 服务端)->...

连接基本没问题了

你知道Socket还可以这样用吗(http中Socket的应用)

创建一个服务端

服务端(只创建一个服务端就OK,不用写客户端)

   try {
          //监听80端口
            ServerSocket serverSocket = new ServerSocket(80);

            Socket accept = serverSocket.accept();

           // InputStream inputStream = accept.getInputStream();


            new SocketThread(accept).start();


        } catch (IOException e) {
            e.printStackTrace();
        }

//------------------------------SocketThread

public class SocketThread extends Thread {

    private Socket mSocket;

    public SocketThread(Socket mSocket) {
        this.mSocket = mSocket;
    }

    @Override
    public void run() {

        try {
          //获取一个读取字符串的流
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));

            String msg = null;
          //获取一个打印流
            PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(mSocket.getOutputStream()),true);
            StringBuilder stringBuilder = new StringBuilder();

            while((msg = bufferedReader.readLine())  != null && !(msg.isEmpty())){
              //接收来自浏览器的消息
                System.out.println("获取到的消息:" + msg);
              //那浏览器的消息加在一起,返回给浏览器
                stringBuilder.append(msg + "\n").append("</br>");
         


            }

          //给浏览器发送消息
           printWriter.println("<!DOCTYPE html>\n" +
                    "<html>\n" +
                    "\t<head>\n" +
                    "\t\t<meta charset=\"GBK\">\n" +
                    "\t\t<title></title>\n" +
                    "\t</head>\n" +
                    "\t<body>\n" + stringBuilder.toString() + "\t</body>\n" +
                    "</html>\n");
            printWriter.flush();
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("出错了:" + e.toString());
        }

    }

浏览器传给我们的消息

image.png

我们给浏览器传的消息

image.png

给浏览器发送消息,也可以想发啥发啥

image.png

改这块

image.png

我发一个稍微复杂一点的(一个表单)

image.png

浏览器的消息

image.png

那我是不是可以提交表单啦???

提交不了的,老哥,浏览器请求到一次,请求完直接就关闭连接了,除非你在创建一个ServletSocket监听

老哥现在对Socket的认识是不是感觉有点不一样?(我*Socket竟然能这样用?)

像上边的应用就相当于TCP

说一下UDP

JAVA当中自带了一个UDP的类

UDP这个是我复制来自这个网站的,应为这个玩意不是怎么经常用

https://www.cnblogs.com/Vito-Yan/p/6919441.html

这个是服务端,作者都写反了。。。

  DatagramSocket ds = null;
        DatagramPacket dp = null;
        byte[] buf = new byte[1024];
        
        ds = new DatagramSocket(3333);
        dp = new DatagramPacket(buf, 1024);
        
        // 接收数据,放入数据报
        ds.receive(dp);
        // 从数据报中取出数据
        String info = new String(dp.getData(),0, dp.getLength());
        System.out.println("接收到的信息是:" + info);
    }

这个是客户端

    public static void main(String[] args) throws Exception {
        DatagramSocket ds = null;
        DatagramPacket dp = null;
        
        // 构建发送对象
        ds = new DatagramSocket();
        // 将数据打包-->打成数据报
        String info = "hello world!";
        
        dp = new DatagramPacket(info.getBytes(), info.length(), InetAddress.getByName("localhost"),3333);
        
        // 发出数据报
        ds.send(dp);
        
    }

----------------------------------------关于Android中Socket的应用

Android中也差不多,只不过用ADB命令映射出来了

adb forward tcp:8888tcp:9999

PC端连接的端口(8888) 
Android写的端口(9999)

强行解释一下

adb命令通过映射 PC端(就是你的电脑端)8888端口

映射到Android端9999端口

比如

//这个是我在Android中监听的服务端(服务端和客户端在那个设备上都没问题,服务端在PC上也没问题 是 在Android上也没问题,客户端同理)
  ServerSocket serverSocket = new ServerSocket(9999);

  ...//你的代码

//--------------------------------Android

//这个是我在电脑中监听的客户端 127.0.0.1 是必须写成这个地址,应为是USB连接,所以映射到本机中了
//记住必须写成 127.0.0.1
Socket socket = new Socket("127.0.0.1", 8888);
 ...//你的代码

Socket 简单的编程讲解完成了,大神们~~~关于Socket实际项目项目当中的应用(比如,我的哥,我这个玩意为什么客户端一断我服务端也断了关闭了-----老哥这个连接只能维持一次,实际项目当中肯定要创建多个Socket 创建一个线程池来维护Socket)

你拉下来也没有Demo

自己动手,理解更加通透(彻底)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345