您的位置:首页 > 编程语言 > Java开发

Netty学习之一--Java socket编程(单线程+多线程)

2017-05-11 17:59 357 查看
1. Socket 通信简介及模型

  Java Socket 可实现客户端--服务器间的双向实时通信。java.net包中定义的两个类socket和ServerSocket,分别用来实现双向连接的client和server端。

    1.1 重要的Socket API:

Accept方法用于产生”阻塞”,直到接受到一个连接,并且返回一个客户端的Socket对象实例。”阻塞”是一个术语,它使程序运行暂时”停留”在这个地方,直到一个会话产生,然后程序继续
GetInputStream方法获得网络连接输入,同时返回一个InputStream对象实例。
GetOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。

         


2. Socket 通信实现方法

2.1  服务器端(单线程)

实例化SeverSocket对象。
调用ServerSocket的accept()方法,生成socket对象,监听从端口上发来的连接请求,等待连接期间会造成阻塞,。
根据生成的客户端的Socket对象,进行读写IO操作。
关闭打开的流和Socket对象。

2.2  客户端

连接客户端指定IP端口,实例化socket对象。
根据生成socket对象,进行读写IO操作。
关闭打开的流和Socket对象。

2.3 服务器端 (多线程)
实例化SeverSocket对象,循环调用accept()等待客户端连接
客户端创建一个socket并请求和服务器端连接
服务器端接受客户端请求,创建socket与该客户建立专线连接
建立连接的两个socket在一个单独的线程上对话
服务器端继续等待新的连接

PS:多线程下服务器发送数据,客户端争抢服务器资源

服务器代码(单线程/单客户端)

import java.io.BufferedReader;
import java.io.IOExc
4000
eption;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketService {
    //搭建服务器端
    public static void main(String[] args) throws IOException{
        SocketService socketService = new SocketService();
        //1、a)创建一个服务器端Socket,即SocketService 
        socketService.oneServer();
    }
    public  void oneServer(){
        try{
            ServerSocket server=null;
            try{
                server=new ServerSocket(3900);
                //b)指定绑定的端口,并监听此端口。
                System.out.println("服务器启动成功");
                //创建一个ServerSocket在端口3900监听客户请求
            }catch(Exception e) {
                    System.out.println("没有启动监听:"+e);
                    //出错,打印出错信息
            }
            Socket socket=null;
            try{
                socket=server.accept();
                //2、调用accept()方法开始监听,等待客户端的连接 
                //使用accept()阻塞等待客户请求,有客户
                //请求到来则产生一个Socket对象,并继续执行
            }catch(Exception e) {
                System.out.println("Error."+e);
                //出错,打印出错信息
            }
            //3、获取输入流,并读取客户端信息 
            String line;
            BufferedReader in=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //由Socket对象得到输入流,并构造相应的BufferedReader对象
            PrintWriter writer=new PrintWriter(socket.getOutputStream());
            //由Socket对象得到输出流,并构造PrintWriter对象
            BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
            //由系统标准输入设备构造BufferedReader对象
            System.out.println("Client:"+in.readLine());
            //在标准输出上打印从客户端读入的字符串
            line=br.readLine();
            //从标准输入读入一字符串
            //4、获取输出流,响应客户端的请求 
            while(!line.equals("end")){
            //如果该字符串为 "bye",则停止循环
                writer.println(line);
                //向客户端输出该字符串
                writer.flush();
                //刷新输出流,使Client马上收到该字符串
                System.out.println("Server:"+line);
                //在系统标准输出上打印读入的字符串
                System.out.println("Client:"+in.readLine());
                //从Client读入一字符串,并打印到标准输出上
                line=br.readLine();
                //从系统标准输入读入一字符串
            } //继续循环

            //5、关闭资源 
            writer.close(); //关闭Socket输出流
            in.close(); //关闭Socket输入流
            socket.close(); //关闭Socket
            server.close(); //关闭ServerSocket
        }catch(Exception e) {//出错,打印出错信息
            System.out.println("Error."+e);
        }
    }
}

客户端代码

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;

public class SocketClient {
    // 搭建客户端
    public static void main(String[] args) throws IOException {
        try {
            // 1、创建客户端Socket,指定服务器地址和端口
             Socket socket=new Socket("127.0.0.1",3900);
            System.out.println("客户端启动成功");
            // 2、获取输出流,向服务器端发送信息
            // 向本机的3900端口发出客户请求
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            // 构造BufferedReader对象
            PrintWriter write = new PrintWriter(socket.getOutputStream());
            // 由Socket对象得到输出流,并构造PrintWriter对象
            //3、获取输入流,并读取服务器端的响应信息 
            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            // 由Socket对象得到输入流,并构造相应的BufferedReader对象
            String readline;
            readline = br.readLine(); // 从系统标准输入读入一字符串
            while (!readline.equals("end")) {
                // 若从标准输入读入的字符串为 "end"则停止循环
                write.println(readline);
                // 将从系统标准输入读入的字符串输出到Server
                write.flush();
                // 刷新输出流,使Server马上收到该字符串
                System.out.println("Client:" + readline);
                // 在系统标准输出上打印读入的字符串
                System.out.println("Server:" + in.readLine());
                // 从Server读入一字符串,并打印到标准输出上
                readline = br.readLine(); // 从系统标准输入读入一字符串
            } // 继续循环
            //4、关闭资源 
            write.close(); // 关闭Socket输出流
            in.close(); // 关闭Socket输入流
            socket.close(); // 关闭Socket
        } catch (Exception e) {
            System.out.println("can not listen to:" + e);// 出错,打印出错信息
        }
    }

}

服务器代码(多线程/多客户端)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class SocketService {
    // 搭建服务器端
    public static void main(String[] args) throws IOException {
        SocketService socketService = new SocketService();
        // 1、a)创建一个服务器端Socket,即SocketService
        socketService.oneServer();
    }

    public void oneServer() {
        try {
            ServerSocket server = null;
            try {
                server = new ServerSocket(3900);
                // b)指定绑定的端口,并监听此端口。
                System.out.println("服务器启动成功");
                // 创建一个ServerSocket在端口3900监听客户请求
            } catch (Exception e) {
                System.out.println("没有启动监听:" + e);
                // 出错,打印出错信息
            }
            Socket socket = null;
            int i = 0;
            int count = 100;// 限制最大连接为100
            while (i++ < count) {
                try {
                    socket = server.accept();
                    System.out.println("当前连接数量:" + i);
                    // 2、调用accept()方法开始监听,等待客户端的连接
                    // 使用accept()阻塞等待客户请求,有客户
                    // 请求到来则产生一个Socket对象,并继续执行
                    Handler handler = new Handler(socket, i);
                    new Thread(handler).start();
                } catch (Exception e) {
                    System.out.println("Error." + e);
                    // 出错,打印出错信息
                }
            }
            server.close(); // 关闭ServerSocket
        } catch (Exception e) {// 出错,打印出错信息
            System.out.println("Error." + e);
        }
    }
}

class Handler implements Runnable {
    private Socket socket;
    private int i;

    public Handler(Socket socket, int i) {
        this.socket = socket;
        this.i = i;
    }

    public void run() {

        BufferedReader in = null;
        PrintWriter writer = null;
        BufferedReader br = null;
        try {
            // 3、获取输入流,并读取客户端信息
            String line;
            in = new BufferedReader(new InputStreamReader(
                    socket.getInputStream()));
            // 由Socket对象得到输入流,并构造相应的BufferedReader对象
            writer = new PrintWriter(socket.getOutputStream());
            // 由Socket对象得到输出流,并构造PrintWriter对象
            br = new BufferedReader(new InputStreamReader(System.in));
            // 由系统标准输入设备构造BufferedReader对象
            System.out.println("Client:"+ i + ":" + in.readLine());
            // 在标准输出上打印从客户端读入的字符串
            line = br.readLine();
            // 从标准输入读入一字符串
            // 4、获取输出流,响应客户端的请求
            while (!line.equals("end")) {
                // 如果该字符串为 "bye",则停止循环
                writer.println(line);
                // 向客户端输出该字符串
                writer.flush();
                // 刷新输出流,使Client马上收到该字符串
                System.out.println("Server:" + line);
                // 在系统标准输出上打印读入的字符串
                System.out.println("Client" + i + ":" + in.readLine());
                // 从Client读入一字符串,并打印到标准输出上
                line = br.readLine();
                // 从系统标准输入读入一字符串
            } // 继续循环

        } catch (Exception e) {
            System.out.println("Error." + e);
            // 出错,打印出错信息
        } finally {
            // 5、关闭资源
            try {
                writer.close(); // 关闭Socket输出流
                in.close();
                socket.close(); // 关闭Socket
            } catch (IOException e) {
                System.out.println("Error." + e);
                // 出错,打印出错信息
            } // 关闭Socket输入流
        }
    }

}

叁考资料:http://www.cnblogs.com/wisdo/p/5860001.html

    
     
     
  



http://blog.csdn.net/qq_23473123/article/details/51461894

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java socket 服务器 通信