java多线程启动BIO和NIO服务端同时启动接受图片和字符数据

main函数:

@MapperScan("com.naughty.userlogin02.dao")
@SpringBootApplication
public class Userlogin02Application  {
    
    

    private final static int AVALIABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();
    private final static ThreadPoolExecutor POOL_EXECUTOR = new ThreadPoolExecutor(AVALIABLE_PROCESSORS, AVALIABLE_PROCESSORS * 2,
            1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(5),
            new ThreadPoolExecutor.CallerRunsPolicy());

//extends SpringBootServletInitializer
    public static void main(String[] args) throws IOException, ExecutionException, InterruptedException {
    
    
//      ServerSocket socket = new ServerSocket(8800);

        SpringApplication.run(Userlogin02Application.class, args);

       TCPserver tcPserver =SpringUtils.getBean(TCPserver.class);
        FutureTask<Integer> future = new FutureTask<Integer>(tcPserver);
        new Thread(future).start();

Myselect myselect =SpringUtils.getBean(Myselect.class);
        FutureTask<Integer> future2 = new FutureTask<Integer>(myselect);
        new Thread(future2).start();


//Thread thread = new Thread();

    // System.out.println("future get"+future.get());
// new Myselect().getSelector();
}


}

BIO服务端:

@Component
public class TCPserver implements Callable {
    
    

private AtomicInteger pic = new AtomicInteger(0);


    public TCPserver() throws IOException {
    
    
    }
//@Async


    @Override
    public Object call() throws Exception {
    
    
        ServerSocket server = new ServerSocket(8003);
        while(true){
    
    
            //(2)开始在这里暂停等待接收客户端的连接,得到一个端到端的Socket管道
            Socket socket = server.accept();
            new ServerReadThread(socket).start();
            System.out.println(socket.getRemoteSocketAddress()+"上线了!");
        }

// 使用accept()阻塞当前线程,等待客户端请求
       // Socket socket = server.accept();


    }
    class ServerReadThread extends Thread {
    
    
        private Socket socket;

        public ServerReadThread(Socket socket) {
    
    
            this.socket = socket;
        }
        @Override
        public void run()
        {
    
    

            try ( // 创建一个ServerSocket监听8080端口的客户端请求

// 由Socket获得输入流,并创建缓冲输入流
                  BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
// 由文件输出流创建缓冲输出流
                  //   System.getProperty("user.dir");
                  FileOutputStream out = new FileOutputStream("C:\\Users\\14172\\Desktop\\myback\\resources\\static\\"+String.valueOf(pic)+".png")) {
    
    
                pic.addAndGet(1);
// 准备一个缓冲区
                byte[] buffer = new byte[1024];
// 首次从Socket读取数据
                int sum = 0;
                int len = in.read(buffer);
                while (len != -1) {
    
    
// 写入数据到文件

                    out.write(buffer, 0, len);
// 再次从Socket读取数据
                    len = in.read(buffer);
                    sum+=len;

                }
                System.out.println("sum"+sum);
                System.out.println("接收完成!");
                System.out.println(Thread.currentThread().getName());
                // return 1;
            } catch (IOException e) {
    
    
                e.printStackTrace();

                //  return 0;
            }finally {
    
    
                try {
    
    
                    socket.close();
                    System.out.println("closed");
                }catch (Exception e){
    
    
                      e.printStackTrace();

                }
            }

        }

}


}

NIO服务端:

package com.naughty.userlogin02.bean;

import com.alibaba.druid.sql.ast.statement.SQLIfStatement;
import com.naughty.userlogin02.service.WashService;
import com.naughty.userlogin02.service.WashServiceImpl;
import com.naughty.userlogin02.util.SpringUtils;
import com.naughty.userlogin02.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;

import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;

/**
 * @Author
 * @Description
 * @Date
 **/
@RestController("Myselect")
public class Myselect implements Callable {
    
    
//
    @Autowired
    private WashService washService;
    @GetMapping("/washbase")
    public List<Wash> getwash()
    {
    
    
        washService.allWash().stream().forEach(System.out::println);
        return washService.allWash();
    }

//@GetMapping("/select")
//    @Bean
//    @Qualifier("select")
    public void getSelector() throws IOException {
    
    
        //创建 Selector
       Selector selector = Selector.open();//用open方法创建
        ServerSocketChannel channel = ServerSocketChannel.open();//获取通道
        channel.configureBlocking(false);//切换为非阻塞模式
        channel.bind(new InetSocketAddress(8004));
        channel.register(selector, SelectionKey.OP_ACCEPT);//注册通道到选择器上,第二个参数为指定的事件为”监听接收事件“
//
//        * 读 : SelectionKey.OP_READ (1)
//* 写 : SelectionKey.OP_WRITE (4)
//* 连接 : SelectionKey.OP_CONNECT (8)
//* 接收 : SelectionKey.OP_ACCEPT (16)
//* 若注册时不止监听一个事件,则可以使用“位或”操作符连接。

        //轮询式的获取选择器上已经“准备就绪”的事件
        while (selector.select() > 0)
        {
    
    

            //7. 获取当前选择器中所有注册的“选择键(已就绪的监听事件)”
            Iterator<SelectionKey> it = selector.selectedKeys().iterator();
            while (it.hasNext())
            {
    
    
                //8. 获取准备“就绪”的是事件
                SelectionKey sk = it.next();
                //9. 判断具体是什么事件准备就绪
                if (sk.isAcceptable()) {
    
    
                    //10. 若“接收就绪”,获取客户端连接
                    SocketChannel sChannel = channel.accept();
                    //11. 切换非阻塞模式
                    sChannel.configureBlocking(false);
                    //12. 将该通道注册到选择器上
                    sChannel.register(selector, SelectionKey.OP_READ);
                } else if (sk.isReadable()) {
    
    
                    //13. 获取当前选择器上“读就绪”状态的通道
                    SocketChannel sChannel = (SocketChannel) sk.channel();
                    //14. 读取数据

                    ByteBuffer buf = ByteBuffer.allocate(5000);
                    int len = 0;
                    FileOutputStream out = new FileOutputStream("C:\\Users\\14172\\Desktop\\myback\\resources\\static\\0.jpg");
                  //  FileOutputStream in = new FileOutputStream("C:\\Users\\14172\\Desktop\\myback\\mydiary.txt");
                    FileChannel fileChannel = out.getChannel();

                    int length=0;
                    if(sChannel.socket().getPort() == 8000)
                    {
    
    

                       try{
    
    
                       // 暂时没有成功,无法接受到图片
                           //FileChannel的read方法 ,从通道读取数据并放到缓冲区中
                        while ((len = sChannel.read(buf)) > 0) {
    
    //把channel的东西读到buf
                            buf.flip();
                  //out.write(buf.array(),0,len);
                            while (buf.hasRemaining())
                            length += fileChannel.write(buf);//buf的数据写到filechannel

                            buf.clear();
                         out.flush();
                            System.out.println("长度" + length);
                        }
                    }finally {
    
    

                       fileChannel.close();

                           out.close();
                       }

                        byte[] buffer = new byte[1024];
// 首次从Socket读取数据

                    //    System.out.println("文件读写完毕");
                    }
                 else  if(sChannel.socket().getPort() == 8002)
                    {
    
    
                        try {
    
    
                            while ((len = sChannel.read(buf)) > 0) {
    
    
                                int alltime = 10;

                                buf.flip();
                                //  out.write(buf.array(),0,len);

                               String readfrompython = new String(buf.array(), 0, len);
                              //  fileChannel.write(buf);
                                 String[] arr = readfrompython.trim().split(",");
                                System.out.println("数据"+readfrompython+"长度"+readfrompython.length());
                            Arrays.stream(arr).forEach(System.out::print);
                                int[] time = new int[arr.length];

                       for (int i = 0; i < arr.length; i++) {
    
    
                           if(!StringUtils.isEmpty(arr[i])) {
    
    
                               time[i] = Integer.parseInt(arr[i]);
                               alltime += time[i];
                           }
                       }

                                System.out.println("total:" + alltime);

                                //wash.setTime(new Date());

                                Wash  wash2 = new Wash();
                                wash2.setLastTime(alltime);

                    //   WashService washService = SpringUtils.getBean("washservice");

                         washService.allWash().stream().forEach(System.out::println);
                           wash2.setTimes(washService.getWahNums()+1);
                           wash2.setAllTime(washService.gettotal()+alltime);//总共清洗时间

                                wash2.setWater(1.2);
                                wash2.setId(100);
                       wash2.setTime(new Date());

                                if(washService.save(wash2)) System.out.println("插入数据成功!");
                                else{
    
    
                                    System.out.println("插入失败");
                                }
                        System.out.println(new String(buf.array(), 0, len));

                                buf.clear();
                            }
                        } finally {
    
    
                        //    if(sChannel.read(buf)<0)
                            fileChannel.close();
                            out.flush();
                            out.close();
                        }
                    }
                }
                //15. 取消选择键 SelectionKey
                it.remove();
            }
        }
    }


    @Override
    public Object call() {
    
    

        System.out.println(Thread.currentThread().getName());
        try {
    
    
getSelector();
        }catch (IOException e)
        {
    
    
            e.printStackTrace();
        }
        return 0;
    }
}

客户端1(接收图片数据)

import os
import sys
import struct

# import win32ui

import socket

host = 'localhost'
port = 8003
bufsize = 1024
addr = (host, port)
mydaar = ('localhost',8012)
filepath = 'C:\\Users\\14172\\PycharmProjects\\pythonProject1\\0.png'

def socket_client():
    try:

        optval = struct.pack("ii", 1, 0)
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind(mydaar)
        # s.setsockopt(socket.SOL_SOCKET, socket.SO_LINGER, optval)
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        # level:选项定义的层次。支持SOL_SOCKET、IPPROTO_TCP、IPPROTO_IP和IPPROTO_IPV6。
        #
        # optname:需设置的选项。
        #
        # value:设置选项的值。
        s.connect((host, port))

    except socket.error as msg:
        print(msg)
        sys.exit(1)

    # print(s.recv(1024).decode("utf-8"))

    while 1:

        fp = open(filepath, 'rb')
        while 1:
            data = fp.read(1024)
            if not data:
                print('{0} file send over...'.format(filepath))
                break
            s.send(data)
        # print(s.recv(1024).decode("utf-8"))
        break

    s.close()


# HTTP断开连接需要经过四次挥手,第四次挥手后为了保证发送的ACK被对方接受需要等待2MSL时间 MSL:报文的最长生存时间

if __name__ == '__main__':
    socket_client()

客户端2(字符数据)


import os
import sys
import struct
# import win32ui

import socket

host = 'localhost'
port = 8004
bufsize = 1024
addr = (host, port)
mydaar = ('localhost',8002)
filepath = 'C:\\Users\\14172\\PycharmProjects\\pythonProject1\\time.txt'

def socket_client():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.bind(mydaar)
        s.connect((host, port))
    except socket.error as msg:
        print(msg)
        sys.exit(1)

    # print(s.recv(1024).decode("utf-8"))

    while 1:

        fp = open(filepath, 'rb')
        while 1:
            data = fp.read(1024)
            if not data:
                print('{0} file send over...'.format(filepath))
                break
            s.send(data)
        # print(s.recv(1024).decode("utf-8"))
        break


if __name__ == '__main__':
    socket_client()


猜你喜欢

转载自blog.csdn.net/qq_41358574/article/details/120609337
今日推荐