java socket 编程

在开始编写代码之前,先来看看socket的通信模型


a.首先写一个socket服务端如下:

public class ServerSocket1 {
    /**
     *1、创建ServerSocket对象,同时绑定监听端口
     * 2、通过accept()方法监听客户端的请求
     * 3、建立连接后,通过输入流读取客户端发送的请求信息
     * 4、通过输出流向客户端发送响应信息
     * 5、关闭相应资源
     */
    public static void main(String[] args)throws Exception {
        //1.创建一个服务端Socket,即ServerSocket对象,指定绑定的端口,并侦听该端口
        ServerSocket serverSocket=new ServerSocket(5555);
        //2.调用accept()方法开始侦听客户端请求,创建Socket,等待客户端的连接
        System.out.println("==============服务即将启动,等待客户端的连接===========");
        
        /**
         * 此处会阻塞,等待客户端调用
         */
    	Socket socket=serverSocket.accept();
        //3.获取输入字节流,读取客户端请求信息
        InputStream is=socket.getInputStream();
        //将字节流包装成字符流
        InputStreamReader isr=new InputStreamReader(is);
        //为字符输入流添加缓冲
        BufferedReader br=new BufferedReader(isr);
        //读取字符输入流中的信息
        String data=null;
        while(null!=(data=br.readLine())){
            System.out.println(new Date());
            System.out.println("我是服务端,客户端说:"+data);
        }
        //调用shutdown方法关闭输入流流
        socket.shutdownInput();
        //4.获取输出字节流,响应客户端的信息
        OutputStream os=socket.getOutputStream();
        //将字节流包装成字符打印流
        PrintWriter pw=new PrintWriter(os);
        //向客户端回应响应消息
        pw.write("用户名的密码输入不正确");
        pw.flush();
        //关闭socket输出流
        socket.shutdownOutput();
        //关闭资源
        pw.close();
        os.close();
        br.close();
        isr.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}
b.在写一个socket客户如下:

public class SocketClient {
    /**
     * 1.创建Socket对象
     * 2.建立连接后,通过输出流向服务器发送请求信息
     * 3.通过输入流获取服务器的响应信息
     * 4.关闭资源
     */
    public static void main(String[] args) throws Exception{
        //1.创建Socket对象
        Socket socket=new Socket("127.0.0.1",5555);
        //2.获取输出字节流,向服务器发送消息
        OutputStream os=socket.getOutputStream();
        //将字节输出流包装为字符打印流
        PrintWriter pw=new PrintWriter(os);
        //向服务器发送请求信息
        StringBuffer sb=new StringBuffer();
        sb.append("用户名:").append("admin");
        sb.append("密码:").append("123");
        pw.write(sb.toString());
        pw.flush();
        //关闭socket的输出流
        socket.shutdownOutput();
        //3.获取输入字节流,读取服务器的响应信息
        InputStream is=socket.getInputStream();
        //将输入字节流包装成字符流
        InputStreamReader isr=new InputStreamReader(is);
        //为字符流添加缓冲区
        BufferedReader br=new BufferedReader(isr);
        //通过服务器端的响应信息
        String data=null;
        while(null!=(data=br.readLine())){
            System.out.println(new Date());
            System.out.println("我是客户端,服务端说:"+data);
        }
        //关闭Socket输入流
        socket.shutdownInput();

        //4、关闭资源
        br.close();
        isr.close();
        is.close();
        pw.close();
        os.close();
        socket.close();
    }
}

以上就完成了基本的socket客户端与服务端的程序。但是该程序的服务端只能完成一次socket请求。

下面对服务器的改造可以完成对客户端的多次请求如下:

a.首先编写一个接受到请求的处理类

/**
 * 创建一个服务端线程,循环侦听客户端的请求
 */
public class ServerThread extends Thread {
    //每当侦听到一个新的客户端时,服务端都需要有一个Socket与之通信
    public Socket socket = null;

    public ServerThread() {
    }

    public ServerThread(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        //获取输入字节流
        InputStream in = null;
        //将输入字节流包装成输入字符流
        InputStreamReader isr = null;
        //为字符输入流添加缓冲
        BufferedReader br = null;
        //收到信息之后,向客户端响应信息,获取输出字节流
        OutputStream out = null;
        //将字节输出流包装成字符打印输出流
        PrintWriter pw = null;
        try {
            in = socket.getInputStream();
            isr = new InputStreamReader(in);
            br = new BufferedReader(isr);

            //读取字符输入流中的数据
            String data = null;
            while ((data = br.readLine()) != null) {
                System.out.println("我是服务器,客户端说:" + data);
            }
            //调用shutDown方法关闭Socket输入流
            socket.shutdownInput();

            out = socket.getOutputStream();
            pw = new PrintWriter(out);
            pw.write("用户名和密码正确");
            pw.flush();

            //调用shutDown方法关闭Socket输出流
            socket.shutdownOutput();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            //关闭资源
            try {
                if (null != pw)
                    pw.close();
                if (null != out)
                    out.close();
                if (null != br)
                    br.close();
                if (null != isr)
                    isr.close();
                if (null != in)
                    in.close();
                if (null != socket)
                    socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

b.然后在启用服务端程序来接受请求

public class ServerSocketMany {
    public static void main(String[] args)throws Exception{
    	System.out.println("服务器已经启动,等待客户端的连接");
        //创建服务器端Socket,即ServerSocket等待客户端请求
        ServerSocket server=new ServerSocket(5555);
        //侦听到的客户端的数量
        int count=0;
        //服务器socket
        Socket socket=null;
        //死循环,让服务器循环侦听
        while(true){
            //服务端开始侦听客户端的连接
            socket=server.accept();
            //启动线程,与客户端进行通信
            Thread serverThread=new ServerThread(socket);
            serverThread.start();
            //计数
            count++;
            System.out.println("当前链接的客户端的数量为:"+count+"个....");
        }
    }
}
c.编写客户端:客户端和上一个版本没有区别。

上文参考博客:http://blog.csdn.net/hu1991die/article/details/40679605


另外:tomcat中的等待连接的实现思路如下:

当有一个请求到达后,tomcat的连接对象,接受该处理后,立马转接到一个线程处理,然后退出该方法,通过此种方式完成了方法的等效异步调用


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值