java的serversocket_Java ServerSocket详解

java的serversocket_Java ServerSocket详解ServerSocket 构造方法 ServerSocket newServerSoc ServerSocket 无参数 ServerSocket intport 指定端口 ServerSocket intport intbacklog 指定端口 队列数 ServerSocket intport intbacklog InetAddre

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();

}

}

}

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/223377.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午2:13
下一篇 2026年3月17日 下午2:13


相关推荐

  • java学生成绩管理系统课程设计源码_设计一个学生成绩管理系统

    java学生成绩管理系统课程设计源码_设计一个学生成绩管理系统项目简介该项目可以分为三个模块:登录模块、主页面模块、信息储存模块。本系统完成了基本所需功能,界面清晰,操作简单又实用,基本满足了学校对学生信息的增添、查询、修改和删除等功能,且具有登录系统使该系统具有一定的安全性,大大减少了操作人员和用户的工作负担,提高了学生管理的工作效率和学校的信息化的水平。功能介绍该项目可以分为三个模块:登录模块、主页面模块、信息储存模块。登录模块实现系统的登录,且具有一键清除的功能;主页面也就是整个系统的核心,包括了对学生信息的增添、查询、修改和删除等功能,还有退出系统的功能

    2025年7月12日
    7
  • dz搬家 config_global.php 不可写入,傻瓜式Discuz论坛搬家教程

    dz搬家 config_global.php 不可写入,傻瓜式Discuz论坛搬家教程1.首先,数据的备份是很重要的,要明确这一点2.论坛搬家,备份恢复一点也不难,真的,首先不要在心里上被它吓到,dz程序为我们提供了非常便捷的几种方案大致上,搬家的方法有几种:1.第一种方法是通过phpmyadmin导出导入数据,这种方法比较鸡肋,因为超过2M的就上传不上去了,在此不多解释,不推荐2.第二种方法是通过ucenter后台自带备份恢复,这个容易遇到“无法访问该应用的备份接口,请拷贝uce…

    2022年7月25日
    9
  • 正弦波放大电路与移相电路设计

    正弦波放大电路与移相电路设计原文地址 http www docin com p 613242880 html 相关文章 1 正弦波放大电路 http zhidao baidu com link url lE4Ox8xWoSal 7C9ZIbVzmGJ4 j2efLU2 Z

    2025年9月6日
    10
  • 求生之路2ping高_DDS信号源

    求生之路2ping高_DDS信号源问答时间:2020年12月17日嘉宾简介:高少星:萌宝集团创始人、稻荷资本创始合伙人、《好玩的书》作者。曾任顺为资本董事总经理、百度高级投资经理,是好大夫、丁香园、一点资讯、宝宝巴士、I…

    2025年7月17日
    8
  • 树莓派连接WiFi(最稳定的方法

    树莓派连接WiFi(最稳定的方法转载:https://i.cmgine.net/archives/11053.html概述树莓派是一个只有信用卡大小的卡片式电脑,基于ARM架构,采用Linux作为其操作系统;它默认是通过有线接口连接互联网,对于如此小巧的设备,有线连接非常不方便,下面我们介绍下如何让树莓派通过无线网卡连接网络。网上大多数文章介绍的是编辑  /etc/network/inte

    2022年6月5日
    778
  • OpenClaw风险全链路分析及安全提示

    OpenClaw风险全链路分析及安全提示

    2026年3月14日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号