(已完成)java socket-服务器端启动流程 源码分析.md

步骤

1.创建服务器端套接字对象
作用 套接字实现类:包含了创建套接字 绑定到ip端口 监听 方法

2.绑定到ip端口
作用 唯一定位到一台机器的一个进程/程序 从而实现不同机器的不同程序的互相通信/读写数据

3.监听
?连接数量还是连接超时时间?

4.接受客户端连接
阻塞 直到有客户端连接进来

应用程序

package simple;



import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.net.ServerSocket;

import java.net.Socket;



/**

 * 服务器端

 * @author gongzhihao

 *

 */

public class Server {

	public static void main(String[] args) {

		try {

			//创建服务器端套接字

			ServerSocket ss = new ServerSocket(8888);

			System.out.println("启动服务器....");

			

			//接受客户端的连接

			Socket s = ss.accept(); //阻塞 直到有客户端连接进来

			System.out.println("客户端:" + s.getInetAddress().getLocalHost() + "已连接到服务器");



			BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));

			// 读取客户端发送来的消息

			String mess = br.readLine();

			System.out.println("客户端:" + mess);

			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

			bw.write(mess + "\n");

			bw.flush();

		} catch (IOException e) {

			e.printStackTrace();

		}

	}

}


复制代码

jdk util包-socket

创建服务器端套接字对象

说明:源码基于jdk8

//服务端套接字类

public

class ServerSocket implements java.io.Closeable {

 




/**

     * The implementation of this Socket.

     */

    private SocketImpl impl; //套接字实现SocksSocketImpl




public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException {

        setImpl(); //套接字实现

        if (port < 0 || port > 0xFFFF)

            throw new IllegalArgumentException(

                       "Port value out of range: " + port);

        if (backlog < 1)

          backlog = 50;

        try {

            bind(new InetSocketAddress(bindAddr, port), backlog);

        } catch(SecurityException e) {

            close();

            throw e;

        } catch(IOException e) {

            close();

            throw e;

        }

    }

复制代码
private void setImpl() {

        if (factory != null) {

            impl = factory.createSocketImpl();

            checkOldImpl();

        } else {

            // No need to do a checkOldImpl() here, we know it's an up to date

            // SocketImpl!

            impl = new SocksSocketImpl(); //问题-套接字实现和ServerSocket区别?

        }

        if (impl != null)

            impl.setServerSocket(this);

    }


复制代码

//bind

public void bind(SocketAddress endpoint, int backlog) throws IOException {

        if (isClosed())

            throw new SocketException("Socket is closed");

        if (!oldImpl && isBound())

            throw new SocketException("Already bound");

        if (endpoint == null)

            endpoint = new InetSocketAddress(0);

        if (!(endpoint instanceof InetSocketAddress))

            throw new IllegalArgumentException("Unsupported address type");

        InetSocketAddress epoint = (InetSocketAddress) endpoint;

        if (epoint.isUnresolved())

            throw new SocketException("Unresolved address");

        if (backlog < 1)

          backlog = 50;

        try {

            SecurityManager security = System.getSecurityManager();

            if (security != null)

                security.checkListen(epoint.getPort());

            getImpl().bind(epoint.getAddress(), epoint.getPort());

            getImpl().listen(backlog);

            bound = true;

        } catch(SecurityException e) {

            bound = false;

            throw e;

        } catch(IOException e) {

            bound = false;

            throw e;

        }

    }


复制代码
/**

     * Get the {@code SocketImpl} attached to this socket, creating

     * it if necessary.

     *

     * @return  the {@code SocketImpl} attached to that ServerSocket.

     * @throws SocketException if creation fails.

     * @since 1.4

     */

    SocketImpl getImpl() throws SocketException {

        if (!created)

            createImpl();

        return impl;

    }




/**

     * Creates the socket implementation.

     *

     * @throws IOException if creation fails

     * @since 1.4

     */

    void createImpl() throws SocketException {

        if (impl == null)

            setImpl();

        try {

            impl.create(true);

            created = true;

        } catch (IOException e) {

            throw new SocketException(e.getMessage());

        }

    }


复制代码

//套接字实现

/* whether this Socket is a stream (TCP) socket or not (UDP)

    */

    protected boolean stream; //问题-tcp utp的区别?




/**

     * The file descriptor object for this socket.

     */

    protected FileDescriptor fd; //问题-套接字的文件描述符对象?







/**

 * Default Socket Implementation. This implementation does

 * not implement any security checks.

 * Note this class should <b>NOT</b> be public.

 *

 * @author  Steven B. Byrne

 */

abstract class AbstractPlainSocketImpl extends SocketImpl

{


/**

     * Creates a socket with a boolean that specifies whether this

     * is a stream socket (true) or an unconnected UDP socket (false).

     */

    protected synchronized void create(boolean stream) throws IOException {

        this.stream = stream; //是tcp还是udp?

        if (!stream) {

            ResourceManager.beforeUdpCreate();

            // only create the fd after we know we will be able to create the socket

            fd = new FileDescriptor(); //套接字的文件描述符?

            try { 

                socketCreate(false); //创建套接字 //没有找到这个方法的最终实现类?

            } catch (IOException ioe) {

                ResourceManager.afterUdpClose();

                fd = null;

                throw ioe;

            }

        } else {

            fd = new FileDescriptor();

            socketCreate(true);

        }

        if (socket != null)

            socket.setCreated();

        if (serverSocket != null)

            serverSocket.setCreated();

    }


复制代码
//jdk7 //这里的代码是jdk7 上面的代码都是jdk8
class PlainSocketImpl extends AbstractPlainSocketImpl

{


native void socketCreate(boolean isServer) throws IOException; //本地方法


复制代码

注意:jdk7也是native方法 但是jdk的native方法没有native关键字

绑定到ip 端口

说明:源码基于jdk7

//ServerSocket

public void bind(SocketAddress endpoint, int backlog) throws IOException {

        if (isClosed())

            throw new SocketException("Socket is closed");

        if (!oldImpl && isBound())

            throw new SocketException("Already bound");

        if (endpoint == null)

            endpoint = new InetSocketAddress(0);

        if (!(endpoint instanceof InetSocketAddress))

            throw new IllegalArgumentException("Unsupported address type");

        InetSocketAddress epoint = (InetSocketAddress) endpoint;

        if (epoint.isUnresolved())

            throw new SocketException("Unresolved address");

        if (backlog < 1)

          backlog = 50;

        try {

            SecurityManager security = System.getSecurityManager();

            if (security != null)

                security.checkListen(epoint.getPort());

            getImpl().bind(epoint.getAddress(), epoint.getPort());

            getImpl().listen(backlog);

            bound = true;

        } catch(SecurityException e) {

            bound = false;

            throw e;

        } catch(IOException e) {

            bound = false;

            throw e;

        }

    }


复制代码

//AbstractPlainSocketImpl

/**

     * Binds the socket to the specified address of the specified local port.

     * @param address the address

     * @param port the port

     */

    protected synchronized void bind(InetAddress address, int lport)

        throws IOException

    {

       synchronized (fdLock) {

            if (!closePending && (socket == null || !socket.isBound())) {

                NetHooks.beforeTcpBind(fd, address, lport);

            }

        }

        socketBind(address, lport);

        if (socket != null)

            socket.setBound();

        if (serverSocket != null)

            serverSocket.setBound();

    }


复制代码

//PlainSocketImpl

 native void socketBind(InetAddress address, int port)

        throws IOException; //本地方法


复制代码
监听

流程和绑定一样

/**

     * Listens, for a specified amount of time, for connections.

     * @param count the amount of time to listen for connections

     */

    protected synchronized void listen(int count) throws IOException {

        socketListen(count); //问题-?

    }


复制代码
native void socketListen(int count) throws IOException;


复制代码

backlog?默认值是50

转载于:https://juejin.im/post/5c4dc6cef265da6153051e44

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值