java的serversocket_Java ServerSocket详解

ServerSocket

构造方法

ServerSocket serverSocket = new ServerSocket();

ServerSocket();//无参数

ServerSocket(int port);//指定端口

ServerSocket(int port,int backlog);//指定端口、队列数

ServerSocket(int port,int backlog,InetAddress bindAddr);//指定端口、队列数、绑定IP

注:当port为0时,随机分配空闲端口。

无参数绑定端口

serverSocket.bind(SocketAddress endpoint);//指定端口

serverSocket.bind(SocketAddress endpoint,int backlog)//指定端口、队列数

ServerSocket选项

SO_TIMEOUT:等待客户连接的超时时间

serverSocket.setSoTimeout(int timeout);//设置(单位为毫秒,为0,则永不超时)

serverSocket.getSoTimeout();//查看超时时间

SO_REUSEADDR:是否允许重用服务器所绑定的地址(需在连接前设置)

serverSocket.setResuseAddress(boolean on);//设置

serverSocket.getResuseAddress();//查看是否开启

SO_RCVBUF:接收数据的缓冲区大小

serverSocket.setReceiveBufferSize(int size);//设置

serverSocket.getReceiveBufferSize();//查看缓冲区大小

设定连接时间、延迟和带宽

参数(相对权重)

三个参数之间的相对大小决定相应参数的相对重要性。

connectionTime:最少时间建立连接

latency:最小延迟

bandwidth:最高带宽

serverSocket.setPerformancePreferences(int connectionTime,int latency,int bandwidth);//设置

ServerSocket信息

serverSocket.getInetAddress();//获取服务器绑定的IP

serverSocket.getLocalPort();//获取服务器绑定的端口

多线程

为每一个连接创建一个线程

重写Runnable方法

Handler.java

package Network_3;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.io.PrintWriter;

import java.net.Socket;

public class Handler implements Runnable {

private Socket socket = null;//初始化Socket

public Handler(Socket socket) {

this.socket = socket;//传入参数

}

/*

*输出流

*/

public PrintWriter getWriter(Socket socket) throws IOException {

OutputStream socketOut = socket.getOutputStream();

return new PrintWriter(socketOut,true);

}

/*

*输入流

*/

public BufferedReader getReader(Socket socket) throws IOException {

InputStreamReader socketIn = new InputStreamReader(socket.getInputStream());

return new BufferedReader(socketIn);

}

//加工信息

public String Echo(String msg) {

return "Echo:"+msg;

}

public void run() {

try {

System.out.println("New Connection "+socket.getInetAddress()+":"+socket.getPort());//打印新连接信息

BufferedReader br = getReader(socket);//输入流

PrintWriter pw = getWriter(socket);//输出流

String msg = null;//初始化msg

while((msg = br.readLine()) != null) {//循环读取一行信息

System.out.println(msg);//打印信息

pw.println(Echo(msg));//将信息加工发送回客户端

if(msg.equals("exit")) {//结束条件

break;

}

}

} catch (IOException e) {

e.printStackTrace();

}finally {

try {

if(socket != null) {//如有连接,关闭

socket.close();

}

}catch (Exception e) {

e.printStackTrace();

}

}

}

}

Server.java

package Network_3;

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

public class Server {

private int port = 8000;//初始化port

private ServerSocket serverSocket = null;//初始化ServerSocket

public Server() {

try {

serverSocket = new ServerSocket(port);//启动服务端

System.out.println("Server Up!");

} catch (IOException e) {

System.out.println("Server Up Error!");

}

}

public void service() {

while(true) {

Socket socket = null;//初始化Socket

try {

socket = serverSocket.accept();//监听连接队列

Thread workThread = new Thread(new Handler(socket)); //创建线程

workThread.start();//启动线程

}catch (Exception e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) {

new Server().service();

}

}

Client.java

package Network_3;

import java.net.*;

import java.io.*;

public class Client {

/*

* 参数初始化

*/

private String host = "127.0.0.1";

private int port = 8000;

private Socket socket;

/*

* 建立连接

*/

public Client() throws IOException {

socket = new Socket(host,port);

}

/*

* 输出流

*/

private PrintWriter getWriter(Socket socket) throws IOException {

OutputStream socketOut = socket.getOutputStream();

return new PrintWriter(socketOut,true);

}

/*

* 输入流

*/

private BufferedReader getReader(Socket socket) throws IOException {

InputStreamReader socketIn = new InputStreamReader(socket.getInputStream());

return new BufferedReader(socketIn);

}

/*

* 客户程序

*/

public void Talk() {

try {

BufferedReader br = getReader(socket);

PrintWriter pw = getWriter(socket);

BufferedReader localReader = new BufferedReader(new InputStreamReader(System.in));

String msg = null;

while((msg = localReader.readLine()) != null) {

pw.println(msg);

System.out.println(br.readLine());

if(msg.equals("exit")) {

break;

}

}

}catch (Exception e) {

e.printStackTrace();

}finally {

try {

socket.close();

}catch (Exception e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) throws UnknownHostException, IOException {

new Client().Talk();

}

}

使用JDK类库提供的线程池

java.util.concurrent包提供

Server.java

package Network_3;

import java.io.IOException;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class Server {

private int port = 8000;//初始化port

private ServerSocket serverSocket = null;//初始化ServerSocket

private ExecutorService executorService = null;//初始化线程池

private final int POOL_SIZE = 4;//单个CPU的线程数

public Server() throws IOException {

serverSocket = new ServerSocket(port);

executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SIZE);//创建线程池,Runtime.getRuntime().availableProcessors()用于返回当前工作环境的CPU数,将CPU数乘单个CPU线程数,得到最终的总线程数。

System.out.println("Server Up");

}

public void service() {

while(true) {

Socket socket = null;

try {

socket = serverSocket.accept();

executorService.execute(new Handler(socket));//Handler与上面的一样

}catch (Exception e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) throws IOException {

new Server().service();

}

}

注意事项

死锁

建议:尽量减少任务之间的依赖。

系统资源不足

建议:根据系统性能设定线程数,回收机制。

并发错误

建议:使用成熟的线程技术。

线程泄露

建议:执行线程任务时,减少与用户的交互(使用超时机制)。

任务过载

建议:控制线程等待队列中的线程数。

关闭服务器

开放一个管理服务器端口,启动守护线程,供管理程序连接,当发送特定字符时,服务器停止向线程池添加任务并等待任务执行完毕或超时,关闭服务程序。

Server.java

package Network_3;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.ServerSocket;

import java.net.Socket;

import java.net.SocketException;

import java.net.SocketTimeoutException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.RejectedExecutionException;

import java.util.concurrent.TimeUnit;

public class Server {

private int port = 8000;//服务端口

private ServerSocket serverSocket = null;//服务Socket

private ExecutorService executorService = null;//线程池

private final int POOL_SIZE = 4;//单个CPU的线程数

private int portForShutdown = 8001;//守护线程端口

private ServerSocket serverSocketForShutdown = null;//守护Socket

private boolean isShutdown = false;//服务器是否关闭

private Thread shutDownThread = new Thread() {//负责关闭服务器的线程

public void start() {

this.setDaemon(true);//设置为守护线程(后台线程)

super.start();

}

public void run() {

while(!isShutdown) {

Socket socketForShutdown = null;

try {

socketForShutdown = serverSocketForShutdown.accept();//开启监听

//获取输入流

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

String command = br.readLine();//读取一行字符

if(command.equals("shutdown")) {//判断是否符合指定字符

long beginTime = System.currentTimeMillis();//开始计数

//输出流输出字符

socketForShutdown.getOutputStream().write("Server Shutdowning\r\n".getBytes());

//服务器关闭

isShutdown = true;

//不再向线程池添加新线程

executorService.shutdown();

//所有任务是否已完成

while(!executorService.isTerminated()) {

//设置线程池中任务的完成超时时间

executorService.awaitTermination(30, TimeUnit.SECONDS);

}

//关闭服务器

serverSocket.close();

long endTime = System.currentTimeMillis();//结束计数

//输出流输出字符

socketForShutdown.getOutputStream().write(("Server Shutdown\r\nTime:"+(endTime-beginTime)+"ms\r\n").getBytes());

//关闭守护线程

socketForShutdown.close();

serverSocketForShutdown.close();

}else {

//不符合特定字符

socketForShutdown.getOutputStream().write("Error".getBytes());

socketForShutdown.close();

}

}catch (Exception e) {

e.printStackTrace();

}

}

}

};

public Server() throws IOException {

//创建Socket

serverSocket = new ServerSocket(port);

serverSocket.setSoTimeout(60000);//设置超时时间

//创建守护Socket

serverSocketForShutdown = new ServerSocket(portForShutdown);

//创建线程池

executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * POOL_SIZE);

//运行守护线程

shutDownThread.start();

System.out.println("Server Up");

}

public void service() {

while(!isShutdown) {

Socket socket = null;

try {

socket = serverSocket.accept();

socket.setSoTimeout(60000);

executorService.execute(new Handler(socket));

}catch (SocketTimeoutException e) {

System.out.println("Client Timeout");

}catch (RejectedExecutionException e) {

try {

if(socket != null) {

socket.close();

}

}catch (IOException x) {

return;

}

}catch (SocketException e) {

if(e.getMessage().indexOf("socket closed") != -1) {

return;

}

}catch (IOException e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) throws IOException {

new Server().service();

}

}

AdminClient.java

package Network_3;

import java.io.BufferedReader;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.net.Socket;

public class AdminClient {

public static void main(String[] args) {

Socket socket = null;

try {

socket = new Socket("localhost", 8001);

OutputStream socketOut = socket.getOutputStream();

socketOut.write("shutdown\r\n".getBytes());

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

String msg = null;

while((msg = br.readLine()) != null) {

System.out.println(msg);

}

}catch (Exception e) {

e.printStackTrace();

}finally {

try {

if(socket != null) {

socket.close();

}

}catch (Exception e) {

e.printStackTrace();

}

}

}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值