Java 网络编程

Scroll Down

Java 网络编程

因为需要研究服务器原理,因而复习一下网络编程

TCP 编程

TCP协议在Java中的两个核心对象是

  1. Socket
  2. ServerSocket

ServerSocket

ServerSocket是服务器对象,可以监听自己开放的端口

通过如下方法获取Socket连接

Socket socket = serverSocket.accept();

如果没有人连接,他会一直等待。

Socket

作为客户端需要创建一个Socket对象,然后对服务器进行连接

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

简单的聊天室

多线程操控,完成多个线程连接服务器,服务器收到通知后再推送给所有线程

服务器端

public class ClientTest {
    public InputStream is;
    public OutputStream os;
    ArrayList<Thread> threads;
    public void creatClient(int time) throws IOException, InterruptedException {
        Socket socket = new Socket("127.0.0.1", 2222);
        os = socket.getOutputStream();
        is = socket.getInputStream();
        threads = new ArrayList<>();

        //复杂发送信息的线程
        Thread outThread = new Thread(new Runnable() {
            @Override
            public void run() {
                OutputStreamWriter outputStreamWriter = new OutputStreamWriter(os);
                PrintWriter writer = new PrintWriter(outputStreamWriter);
                Scanner scanner = new Scanner(System.in);
                while (true)
                {
                    String line = scanner.nextLine();
                    writer.println(line);
                    writer.flush();
                }
            }
        });
        
        //接收线程
        Thread readThread = new Thread(new Runnable() {
            @Override
            public void run() {
                InputStreamReader inputStreamReader = new InputStreamReader(is);
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                String line = "";
                try {
                    while ((line = bufferedReader.readLine())!=null)
                    {
                        System.out.println("接收信息");
                        System.out.println(line);
                        System.out.println("=========");
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }finally {
                    try {
                        bufferedReader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        threads.add(readThread);
        threads.add(outThread);
        readThread.start();
        outThread.start();


        //到一定时间关闭程序
        Thread.sleep(time);
        try {
            for (Thread thread : threads) {
                thread.stop();
            }
            os.close();
            is.close();
            socket.close();
            System.out.println("关闭流");
        } catch (IOException e) {
            e.printStackTrace();
        }
        

    }
}

客户端

public class ServerTest {
    //存放所有socket连接
    public static ArrayList<Socket> sockets;
    static {
        sockets = new ArrayList<>();
    }
    public static class Client implements Runnable{
        Socket socket;
        public Client(Socket socket)
        {
            this.socket = socket;
        }
       	
        @Override
        public void run() {
            OutputStream os;
            InputStream is = null;
            try {
                os = socket.getOutputStream();
                is = socket.getInputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            String line = "";
            try {
                while ((line=reader.readLine())!=null)
                {
                    System.out.println("接收信息 ");
                    System.out.println(line);
                    System.out.println("========");
                    //每次接收到消息都进行广播
                    for (Socket s : sockets) {
                        OutputStreamWriter outputStreamWriter = new OutputStreamWriter(s.getOutputStream());
                        PrintWriter writer = new PrintWriter(outputStreamWriter);
                        writer.println(line);
                        writer.flush();
                    }
                }
            }catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ServerSocket serverSocket = new ServerSocket(2222);
		//不断监听
        while (true)
        {
            Socket socket = serverSocket.accept();
            sockets.add(socket);
            new Thread(new Client(socket)).start();
        }
        
    }
}

注意事项

一定要关闭流再结束程序,否则报异常

UDP通信

UPD通信没有名义上的服务器和客户端,都是可以相互发送信息的,信息以包的形式包装

核心对象

  1. DatagramSocket
  2. DatagramPacket

服务器端

//设置发送出去的端口号
DatagramSocket socket = new DatagramSocket(11011);
byte[] bytes = new byte[1024];

//创建发送的数据包
//设置地址,接收端口号
DatagramPacket datagramPacket = new DatagramPacket(bytes,0,bytes.length,InetAddress.getByName("localhost"),9090);

datagramPacket.setData("hello".getBytes());

socket.send(datagramPacket);

客户端

//设置接收端口号
DatagramSocket socket = new DatagramSocket(9090);

byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, 0, bytes.length);

//接收数据
socket.receive(datagramPacket);
byte[] data = datagramPacket.getData();

System.out.println(new String(data));