• 套接字 Socket 和 ServerSocket 讲解和实例


    什么是Socket?

    网络上两个程序通过一个双向的通信链接实现数据的交换,这个链接的一端称为一个Socket

     

    先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。

    建立网络连接至少需要一对端口号。

    Socket 套接字是网络连接的一个端点,套接字使一个应用可以从网络中读取和写入数据,放到不同的计算机上,可以使两个应用通过连接发送和接收字节流,为了让一个应用发送数据到另一个应用,你需要知道另一个应用的IP地址和接口(其实是服务端的域名和接口)

    public Socket (java.lang.String host, int port)

    一旦建立成功,你就可以用它接收和发送字节流。要发送时你需要用到Socket类中的getOutputStream方法来获取一个java.io.OutputStream对象。要送出字节流,你需要从返回的OutputStream对象中构造一个java.io.PrintWriter对象。

    同时你要接收字节流可以调用Socket类中的getInputStream方法来返回一个java.io.InputStream对象。

    ServerSocket 服务端套接字,由于服务端和客户端不一样要随时待命,所以就用到java.net.ServerSocket类。一旦获得一个连接的请求,就会创建一个Socket来和客户端进行通信。

    它有4个构造方法, port是端口, backlog是能承受的连接数,服务端的IP,默认是127.0.0.1(本机的IP)

    public ServerSocket() ,
    public ServerSocket(int port),
    public ServerSocket(int port, int backlog),
    public ServerSocket(int port, int backlog, InetAddress bindAddr)

    一个小的Demo
    客户端:
    import java.io.*;
    import java.net.Socket;

    public class Client {
    public static void main(String[] args){
    while(true){
    try{
    Socket s = new Socket("10.10.10.124",8088);
    OutputStream o = s.getOutputStream();
    PrintWriter pw = new PrintWriter(o);
    System.out.print("请输入: ");
    String str = new BufferedReader(new InputStreamReader(System.in)).readLine();
    pw.write(str);
    pw.flush();
    s.shutdownOutput();//关闭输出流,这个并不是关闭了连接,而是关闭了流,目的为了防止在一个流中出现输入、输出交叉影响会先设置好输出输入的先后顺序,然后在写入客户端或者服务端的时候,要将优先使用过的输入输出流进行暂时性关闭,保证输入输出流的数据流畅和准确性!
    InputStream is=s.getInputStream();
    BufferedReader br=new BufferedReader(new InputStreamReader(is));
    String info= br.readLine();
    if ("OK".equals(info)) {
    System.out.println("客户端将关闭连接");
    Thread.sleep(500);
    break;
    }
    System.out.println("我是客户端,服务器说:"+info);
    br.close();
    is.close();
    pw.close();
    o.close();
    s.close();
    }catch (Exception e){
    e.printStackTrace();
    }
    }
    }
    }
    客户端结果:

    请输入: 你好
    我是客户端,服务器说:你好
    请输入: 我是客户端
    我是客户端,服务器说:我是服务端
    请输入: 见到你很高兴
    我是客户端,服务器说:我也是,见到你很高兴
    请输入: 测试就到这里吧
    客户端将关闭连接


    服务端
    import com.sdy.im.socket.ServerThread;

    import java.net.InetAddress;
    import java.net.ServerSocket;
    import java.net.Socket;

    public class Server {
    public static void main(String[] args) {
    try {
    ServerSocket ss = new ServerSocket(8088);
    Socket s = null;
    int count = 0;
    System.out.println("***服务器即将启动,等待客户端的连接***");
    while (true) {
    s = ss.accept();
    ServerThread st = new ServerThread(s);
    st.start();
    count++;
    System.out.println("客户端的数量:" + count);
    InetAddress address = s.getInetAddress();
    System.out.println("当前客户端的IP:" + address.getHostAddress());
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }
    import java.io.*;
    import java.net.Socket;

    public class ServerThread extends Thread{
    Socket socket = null;
    public ServerThread(Socket socket) {
    this.socket = socket;
    }
    public void run() {
    InputStream is = null;
    InputStreamReader isr = null;
    BufferedReader br = null;
    OutputStream os = null;
    PrintWriter pw = null;
    try {
    is = socket.getInputStream();
    isr = new InputStreamReader(is);
    br = new BufferedReader(isr);
    String info = null;
    while ((info = br.readLine()) != null) {//循环读取客户端的信息
    System.out.println("我是服务器,客户端说:" + info);
    }
    socket.shutdownInput();//关闭输入流
    os = socket.getOutputStream();
    System.out.print("请输入: ");
    // 发送键盘输入的一行
    String s = new BufferedReader(new InputStreamReader(System.in)).readLine();
    pw = new PrintWriter(os);
    pw.write(s);
    pw.flush();//调用flush()方法将缓冲输出
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    try {
    if (pw != null) {
    pw.close();
    }
    if (os != null) {
    os.close();
    }
    if (br != null) {
    br.close();
    }
    if (isr != null) {
    isr.close();
    }
    if (is != null) {
    is.close();
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }
    }

    服务端结果:

    我是服务器,客户端说:你好
    请输入: 你好
    客户端的数量:14
    当前客户端的IP:10.10.10.124
    我是服务器,客户端说:我是客户端
    请输入: 我是服务端
    客户端的数量:15
    当前客户端的IP:10.10.10.124
    我是服务器,客户端说:见到你很高兴
    请输入: 我也是,见到你很高兴
    客户端的数量:16
    当前客户端的IP:10.10.10.124
    我是服务器,客户端说:测试就到这里吧
    请输入: OK

    参考: https://www.cnblogs.com/baxianhua/p/9287836.html

    https://blog.csdn.net/qq_41517936/article/details/81015711

  • 相关阅读:
    【递推】【概率】Gym
    【坐标变换】【二维偏序】【线段树】Gym
    【DLX算法】hdu3498 whosyourdaddy
    【DLX算法】poj2676 Sudoku
    【Pollard-rho算法】【DFS】poj2429 GCD & LCM Inverse
    Pollard-rho算法:模板
    【筛法求素数】【推导】【组合数】UVALive
    【二项式定理】【DFS】UVALive
    【并查集】【枚举倍数】UVALive
    【Floyd算法】Gym
  • 原文地址:https://www.cnblogs.com/echo777/p/11793916.html
Copyright © 2020-2023  润新知