Java Socket网络编程Server端详解

Socket通信:分为客户端和服务端的socket代码。

Java SDK提供一些相对简单的Api来完成.对于Java而言.这些Api存在与java.net 这个包里面.因此只要导入这个包就可以开始网络编程了。

  网络编程的基本模型就是客户机到服务器模型。简单的说就是两个进程之间相互通讯,然后其中一个必须提供一个固定的位置,而另一个则只需要知道这个固定的位置。并去建立两者之间的联系,然后完成数据的通讯就可以了。这里提供固定位置的通常称为服务器,而建立联系的通常叫做客户端。了解这个简单的模型,就可以网络编程了。 Java对这个模型的支持有很多种Api。而这里我只想介绍有关Socket的编程接口,对于Java而言已经简化了Socket的编程接口。

创建服务器端实例有四种构造函数可以实现(Java提供了ServerSocket来对其进行支持):  

  

首先,我们来讨论有关提供固定位置的服务方是如何建立的。事实上当你创建该类的一个实力对象并提供一个端口资源你就建立了一个固定位置可以让其他计算机来访问你。

ServerSocket server=new ServerSocket(int port);  //port - 端口号;或者为 0,表示使用任何空闲端口。

这里稍微要注意的是端口的分配必须是唯一的。因为端口是为了唯一标识每台计算机唯一服务的,另外端口号是从0~65535之间的,前1024个端口已经被Tcp/Ip 作为保留端口,因此你所分配的端口只能是1024个之后的。

创建绑定到特定端口的服务器套接字。端口 0 在所有空闲端口上创建套接字。输入连接指示(对连接的请求)的最大队列长度被设置为 50。如果队列满时收到连接指示,则拒绝该连接。

其次,创建非绑定服务器。

ServerSocket server=new ServerSocket();  //创建非绑定服务器套接字

  

第三,创建指定端口,最大连接数的服务器。

ServerSocket server=new ServerSocket(int port,int backlog); //port - 指定的端口;或者为 0,表示使用任何空闲端口。backlog - 队列的最大长度。

利用指定的 backlog 创建服务器套接字并将其绑定到指定的本地端口号。端口号 0 在所有空闲端口上创建套接字。输入连接指示(对连接的请求)的最大队列长度被设置为 backlog 参数。如果队列满时收到连接指示,则拒绝该连接。backlog 参数必须是大于 0 的正值。如果传递的值等于或小于 0,则假定为默认值。

  

第四,创建指定端口,最大连接数,指定IP的服务器。

ServerSocket server=new ServerSocket(int port,int backlog,InetAddress bindAddr);//port - 本地 TCP 端口;backlog - 侦听
//backlog;bindAddr - 要将服务器绑定到的 InetAddress 

使用指定的端口、侦听 backlog 和要绑定到的本地 IP 地址创建服务器。bindAddr 参数可以在 ServerSocket 的多穴主机 (multi-homed host) 上使用,ServerSocket 仅接受对其地址之一的连接请求。如果 bindAddr 为 null,则默认接受任何/所有本地地址上的连接。端口必须在 0 到 65535 之间(包括两者)。

服务器端实例创建完成以后,就可以使用线程池来处理客户端发来的请求数据了。

ExecutorService pool = Executors.newFixedThreadPool(int poolSize); //poolSize 固定线程池大小

下面给出了一个网络服务的简单结构,这里线程池中的线程作为传入的请求。它使用了预先配置的 Executors.newFixedThreadPool(int) 工厂方法:

ServerThread.java

public class ServerThread extends Thread //此处亦可以实现Runnable接口
{
    private InputStream ins = null;
    private PrintWriter out = null;

    public ServerThread(Socket socket)
    {
        try
        {
            ins = socket.getInputStream();
            out = new PrintWriter(socket.getOutputStream(), true);
            socket.setSoTimeout(1000);
        }
        catch (IOException e)
        {
            e.printStackTrace();
            interrupt(); // 如果发生异常 则终止线程
        }
    }

    public void run()
    {
        try
        {
            // 初始化构造函数以后会执行到这里
            //从输入流中取出数据并转换成字符串格式
            //处理客户端请求过来的相应数据,并做处理
            String instr = "";
            int temp = -1;
            List<Byte> byteList = new ArrayList<Byte>();
            while(true)
            {
                try
                {
                    temp = ins.read();
                    if(temp != -1)
                    {
                        byteList.add(new Byte((byte)temp));
                    }
                    else
                    {
                        break;
                    }
                }
                catch (IOException e)
                {
                    break;
                }
            }

            byte[] bytes = new byte[byteList.size()];
            for(int i=0;i<byteList.size();i++)
            {
                bytes[i] = byteList.get(i);
            }

            instr = new String(bytes);//将byte数组类型转换为字符串
            System.out.println("the content of recivedMessage is:" + instr); // 这里用日志文件记录下收到的报文
            out.println("Request Message has been receiver!");
            out.flush();
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }
}

ServerSocketDemo.java

public class ServerSocketDemo extends Thread
{
    private  ServerSocket server = null;
    private int port = 0;
    private int poolsize = 0;
    private int maxconn = 0;

    public ServerSocketDemo(int port, int poolSize,int maxconn)
    {
        System.out.println("port is:>>>>>>"+port);
        System.out.println("poolSize is:>>>>>>"+poolSize);
        System.out.println("maxconn is:>>>>>>"+maxconn);

        this.port = port;
        this.poolsize = poolSize;
        this.maxconn = maxconn;
    }

    public void run()
    {
        try
        {
            System.out.println("the poolsize is:>>>>" + poolsize);
            System.out.println("the port is:>>>>" + port);
            System.out.println("the maxconn is:>>>>" + maxconn);
            // 使用固定大小线程池
            ExecutorService thredpool = Executors.newFixedThreadPool(poolsize);
            server = new ServerSocket(port, maxconn);
            server.setSoTimeout(0); // 设置不会超时
            System.out.println("socket listener start!the port is:>>>>" + port
                    + " and the maxConn number is:" + maxconn
                    + "and the Thread Pool size is" + poolsize);

            while (true)
            {
                thredpool.execute(new ServerThread(server.accept()));
                System.out.println("a ServerThread has been started!");
            }
        }
        catch (Exception e)
        {
            // 这里要用日志文件记录异常
            System.out.println(
                    "The serversocket listener exception occurred! the exception msg is>>>>"
                            + e.getMessage());
        }
    }
}

ServerSocketTest.java

public class ServerSocketTest {

    /**
     * @param args
     */
    public static void main(String[] args)
    {
        // TODO Auto-generated method stub

        ServerSocketDemo ssd = new ServerSocketDemo(9997,50,100);
        ssd.start();
    }

}

时间: 2024-08-24 13:53:24

Java Socket网络编程Server端详解的相关文章

Java Socket网络编程Client端详解

此类实现客户端套接字(也可以就叫“套接字”).套接字是两台机器之间的通信端点. Socket client = new Socket(ip,port);//创建一个流套接字并将其连接到指定 IP 地址的指定端口号. 以下为完整的客户端示例: SocketClientDemo.java public class SocketClientDemo { /** * 向指定的地址发送请求数据 * @param ipAddr * @param reqData */ public void sendReq(

Java Socket 网络编程心跳设计概念

Java Socket 网络编程心跳设计概念 1.一般是用来判断对方(设备,进程或其它网元)是否正常动行,一 般采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经当掉.用于检测TCP的异常断开.一般是用来判断对方(设备,进程或其它 网元)是否正常动行,一般采用定时发送简单的通讯包,如果在指定时间段内未收到对方响应,则判断对方已经当掉.用于检测TCP的异常断开.基本原因是服务 器端不能有效的判断客户端是否在线也就是说,服务器无法区分客户端是长时间在空闲,还是已经掉线的情况.

java socket 网络编程

一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的一台主机. 而TCP层则提供面向应用的可靠(tcp)的或非可靠(UDP)的数据传输机制,这是网络编程的主要对象,一般不需要关心IP层是如何处理数据的. 目前较为流行的网络编程模型是客户机/服务器(C/S)结构.即通信双方一方作为服务器等待客户提出请求并予以响应.客户则

Java Socket网络编程的经典例子(转)

事实上网络编程简单的理解就是两台计算机相互通讯数据而已,对于程序员而言,去掌握一种编程接口并使用一种编程模型相对就会显得简单的多了,Java SDK提供一些相对简单的Api来完成这些工作.Socket就是其中之一,对于Java而言,这些Api存在与java.net 这个包里面,因此只要导入这个包就可以准备网络编程了. 网络编程的基本模型就是客户机到服务器模型,简单的说就是两个进程之间相互通讯,然后其中一个必须提供一个固定的位置,而另一个则只需要知道这个固定的位置.并去建立两者之间的联系,然后完成

java socket网络编程(多线程技术)

Client.java import java.io.*; import java.net.*; import java.util.*; public class Client { public static void main(String args[]) { Scanner scanner = new Scanner(System.in); Socket mysocket=null; DataInputStream in=null; DataOutputStream out=null; Th

Java Socket网络编程

服务器端: 1 import java.net.*; 2 import java.io.*; 3 public class SocketServer extends Thread { 4 private ServerSocket serverSocket; 5 public SocketServer(int port) throws IOException 6 { 7 serverSocket=new ServerSocket(port); 8 //等待客户连接的时间不超过6秒 9 server

JAVA SOCKET网络编程,服务端接收多个客户端连接的实现

这是基于前面一篇文章的一个简单扩展,当然这不是最好的实现 服务端如果要想接收多个客户端连接,必须死循环去接收新的客户端的连接请求,一个完整的客户端服务端socket连接通过一个线程来维护 package com.tree.demo.socket; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.n

Java Socket网络编程常见异常(转)

转:https://www.cnblogs.com/qq78292959/p/5085559.html 1.java.net.SocketTimeoutException 这个异常比较常见,socket超时.一般有2个地方会抛出这个: a.一个是connect的时候,这个超时参数由connect(SocketAddress endpoint, int timeout)中的后者来决定, b.还有就是setSoTimeout(int timeout),这个是设定读取的超时时间.他们设置成0均表示无限

Java - TCP网络编程

Java - TCP网络编程 Server 逻辑思路: 创建ServerSocket(port),然后服务器的socket就启动了 循环中调用accept(),此方法会堵塞程序,直到发现用户请求,返回用户的socket 利用多线程对用户socket进行IO操作 注意:对Scoket/File进行创建.关闭,都需要放try catch中,检测 IOException,所以将网络IO部分整体放入try catch中即可. 1. 字符串操作 输出:PrintWriter out=new PrintWr