首页 > 代码库 > java点滴之ServerSocket的使用
java点滴之ServerSocket的使用
一概念
serversocket 建立的是socket的服务端,socket建立的是客户端。最主要构造方法:
public ServerSocket():创建一个未绑定任何端口的套接字,通过该方法创建的 ServerSocket 不与任何端口绑定, 接下来还需要通过 bind() 方法与特定端口绑定. 这个默认构造方法的用途是, 允许服务器在绑定到特定端口之前, 先设置ServerSocket 的一些选项. 因为一旦服务器与特定端口绑定, 有些选项就不能再改变了.
public ServerSocket(int port):创建一个绑定指定端口的套接字,0代表端口号是自动分配的,并默认最大只允许
50个连接请求,在请求没有被accept()之前,如果Client再请求连接,就会被Server拒绝。
ServerSocket(int port, int backlog, InetAddress bindAddr):参数:指定端口号,最大连接数,bindAddr显式指定服务器要绑定的IP地址.
setReuseAddress(true)方法:
可以允许多个socket
绑定到相同的IP地址和端口,那么发送到此IP地址和端口的数据能够被复制到多个socket,
也就是说能够实现多播的功能。(我知道多播程序用MutilcastSocket类) ,
setReuseAddress() 必须在socket绑定到端口之前调用才有效, 如果端口忙,但TCP状态位于 TIME_WAIT ,可以重用 端口。如果端口忙,而TCP状态位于其他状态,重用端口时依旧得到一个错误信息, 抛出“Address already in use: JVM_Bind”。如果你的服务程序停止后想 立即重启,不等60秒,而新套接字依旧 使用同一端口,此时 SO_REUSEADDR 选项非常有用。必须意识到,此时任何非期 望数据到达,都可能导致服务程序反应混乱,不过这只是一种可能,事实上很不可能。
二服务端处理线程提供的方法
public synchronized boolean start() { mHttpServerThread = new Thread(this); mHttpServerThread.setName("HTTP Accept Thread" + ":" + mBindPort); // httpServerThread.setPriority(Thread.MIN_PRIORITY); mHttpServerThread.setDaemon(true); mHttpServerThread.setPriority(Thread.MAX_PRIORITY); bHttpServerThreadFlag = true; mHttpServerThread.start(); return true; }
2.业务方法
public void run() { if (isOpened() == false) return; // Thread Pool ExecutorService exeutor = Executors.newCachedThreadPool(); Thread thisThread = Thread.currentThread(); DLog.i(mTAG, "run", "http server started!!!!"); while (bHttpServerThreadFlag && mHttpServerThread != null && thisThread != null && mHttpServerThread.equals(thisThread)) { Thread.yield(); Socket sock = null; try { while (HTTPServerThread.usedServerSocket > HTTPServerThread.MAX_SERVER_SOCKET) { Thread.yield(); } synchronized (mAcceptSocketList) { sock = accept(); if (sock != null) { // CTT 2.0 // accepted socket is added to arrayList using // WeakReference // the socket SHOULD be closed when http server is // stopped mAcceptSocketList.add(new WeakReference<Socket>(sock)); exeutor.execute(new HTTPServerThread(this, sock)); ++HTTPServerThread.usedServerSocket; } } if (isOpened() == false) break; // http server is closed. } catch (Exception e) { if (sock != null) { try { sock.close(); } catch (IOException e1) { DLog.w(mTAG, "run", "run - IOException", e); } } DLog.w(mTAG, "run", "run - IOException", e); continue; } } // Thread Pool exeutor.shutdown(); DLog.i(mTAG, "run", "http server stopped!!!!"); }
public boolean open(int port) { if (mServerSock != null) return true; try { mBindPort = port; // Debug.error("HTTPServer", "Address: " + MediaServer.ipAddress + // String.valueOf(port)); mServerSock = new ServerSocket(mBindPort, 512); mServerSock.setSoTimeout(HTTP.DEFAULT_TIMEOUT * 1000 + 5000); mServerSock.setReuseAddress(true); } catch (IOException e) { DLog.w(mTAG, "open", "Open - IOException", e); return false; } return true; }
4.阻塞接收请求
public Socket accept() { Socket sock = null; if (mServerSock == null || mServerSock.isClosed()) return null; try { sock = mServerSock.accept(); sock.setSoTimeout(HTTP.DEFAULT_TIMEOUT * 1000 + 5000); // add margin sock.setReceiveBufferSize(HTTP.DEFAULT_CHUNK_SIZE); sock.setSendBufferSize(HTTP.DEFAULT_CHUNK_SIZE); // sock.setSoLinger(true, HTTP.DEFAULT_TIMEOUT); DLog.d(mTAG, "open", "accept :" + String.valueOf(sock.getSendBufferSize())); return sock; } catch (SocketTimeoutException e1) { return null; } catch (Exception e) { try { if (sock != null) sock.close(); } catch (IOException e1) { e = e1; } DLog.w(mTAG, "open", "accept Exception :" + e.toString(), e); return null; } }5.服务线程的停止
public synchronized boolean stop() { close(); bHttpServerThreadFlag = false; DLog.i(mTAG, "stop", "Wait start for finishing thread !!!"); if (mHttpServerThread != null && mHttpServerThread.isAlive()) { try { mHttpServerThread.join(); } catch (InterruptedException e) { DLog.w(mTAG, "stop", "Thread Join InterruptedException", e); } } DLog.i(mTAG, "stop", "Wait done for finishing thread !!!"); mHttpServerThread = null; // CTT 2.0 // Accepted socket SHOULD be closed synchronized (mAcceptSocketList) { for (WeakReference<Socket> sockRef : mAcceptSocketList) { try { Socket sock = sockRef.get(); if (sock != null) { sock.close(); } } catch (IOException e) { DLog.w(mTAG, "stop", "Error: socket - IOException", e); } } mAcceptSocketList.clear(); } return true; }6.服务线程的关闭
public boolean close() { if (mServerSock == null) return true; try { mServerSock.close(); } catch (Exception e) { DLog.w(mTAG, "open", "Close - Exception :", e); return false; } finally { mServerSock = null; mBindPort = 0; } return true; }