网络编程.md

1 网络编程基本概念

2 网络编程TCP协议

1、 TCP 程序概述

Tcp 是一个可靠的协议,面向连接的协议

实现TCP程序,需要编写服务器端和客户端,Java API 为我们提供le Java.net 包,为实现网络应用程序提供类。

ServerSocket: 此类实现服务器套接字

Socket: 此类实现客户端套接字

Socket 是网络驱动层提供给应用程序编程的接口和一种机制。

实现服务器端与客户端程序

客户端:

public class Socket extends Object 套接字是两台机器间通信的端点

Socket(String host, int port): 创建一个流套接字并将其连接到指定主机上的指定端口号

InputStream getInputSream() 返回此套接字的输入流

OutputStream getOutputStream() 返回此套接字的输出流

void setSoTimeout(int timeout) 启用/禁用带有指定超时值的SO_TIMEOUT, 以毫秒为单位

Echo: 意思为应答,程序的功能是客户端向服务器发送一个字符串,服务器不做任何处理,直接把字符串返回给客户端,Echo 程序是最为基本的客户/ 服务器程序

3 TCP实现ECHO程序

public class EchoClientDemo {
    public static void main(String[] args){
        // 创建一个Socket 对象,指定要连接的服务器
        try {
            Socket socket = new Socket("localhost",6666);

            // 获取socket 的输入输出流
            PrintStream ps = new PrintStream(new BufferedOutputStream(socket.getOutputStream()));
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            ps.println("hello");

            ps.flush();
            String info = br.readLine();
            System.out.println(info);
        } catch (IOException e) {
            e.printStackTrace();
        }



    }
}
public class EchoServerDemo {
    public static void main(String[] args){

            try {
                ServerSocket server  = new ServerSocket(6666);
                System.out.println("服务器已经启动,等待客户端连接");
                Socket socket = server.accept();
                BufferedReader br = new BufferedReader(
                        new InputStreamReader(socket.getInputStream()));
                String info = br.readLine(); // 通过输入流读取网络数据, 如果没有数据,那么会阻塞
                System.out.println(info);

                // 获取输出流,向客户端返回消息
                PrintStream ps = new PrintStream(new
                        BufferedOutputStream(socket.getOutputStream()));

                ps.println("echo"+ info);
                ps.flush();
                ps.close();
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }




    }
}

4 服务器与多客户端通信

目前为止我们编写的程序中,服务器只能同时处理一个客户端连接,要想服务器同时支持多个客户端的连接,就必须加入多线程的处理机制,将每一个连接的客户端都创建一个新的线程对象

// 用来处理客户端请求的线程任务
public class MultiServerDemo {
    public static void main(String[] args) {
        ExecutorService es = Executors.newFixedThreadPool(3);
        try {
            ServerSocket server = new ServerSocket(6666);
            System.out.println("服务器已经启动,正在等待连接");
            while (true) {
                Socket s = server.accept();
                System.out.println(s.getInetAddress().getHostAddress());
                es.execute(new UserThread(s));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

// 用来处理客户端请求的线程任务
class UserThread implements Runnable {
    private Socket s;

    public UserThread(Socket s) {
        this.s = s;
    }

    public void run() {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            PrintStream ps = new PrintStream(new BufferedOutputStream(s.getOutputStream()));
            String info = br.readLine();
            System.out.println(info);
            ps.println("echo " + info);
            ps.flush();
            ps.close();
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

5 多客户端之间的通信

服务器可以与多个客户端实现通信了,那我们真正的目的是要实现多个客户端之间的通信,使用TCP协议实现的方案是: 客户端将数据包通过服务器中转,发送到另一个客户端。

public class MultiServerDemo {
    public static void main(String[] args) {
        ExecutorService es = Executors.newFixedThreadPool(3);
        try {
            ServerSocket server = new ServerSocket(6666);
            System.out.println("服务器已经启动,正在等待连接");
            while (true) {
                Socket s = server.accept();
                System.out.println(s.getInetAddress().getHostAddress());
                es.execute(new UserThread(s));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

// 用来处理客户端请求的线程任务
class UserThread implements Runnable {
    private Socket s;

    public UserThread(Socket s) {
        this.s = s;
    }

    public void run() {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            PrintStream ps = new PrintStream(new BufferedOutputStream(s.getOutputStream()));
            String info = br.readLine();
            System.out.println(info);
            ps.println("echo " + info);
            ps.flush();
            ps.close();
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
public class MultiClientDemo {
    public static void main(String[] args){
        Scanner input = new Scanner(System.in);
        // 创建一个Socket 对象,指定要连接的服务器
        try {
            Socket socket = new Socket("localhost",6666);

            // 获取socket 的输入输出流
            PrintStream ps = new PrintStream(new BufferedOutputStream(socket.getOutputStream()));
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));

            System.out.println("请输入:");
            String info = input.nextLine();

            ps.println(info);

            ps.flush();
            info = br.readLine();
            System.out.println(info);
        } catch (IOException e) {
            e.printStackTrace();
        }



    }
}

6 网络编程UDP协议

UDP 是User Datagram protocol 简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,他在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性不能保证,每个被传输的数据报必须限定在64KB之内。

DatagramPacket: 此类表示数据报包

DatagramSocket: 表示用来发送和连接数据报包的套接字

public class UDPServerDemo {
    public static void main(String[] args) {
        String info = "good good 学习, 天天 up up";
        byte[] bytes = info.getBytes();
        DatagramPacket dp;
        try {
            dp = new DatagramPacket(
                    bytes,
                    0,
                    bytes.length,
                    InetAddress.getByName("127.0.0.1"),
                    8888);
            DatagramSocket socket = new DatagramSocket(9000);
            socket.send(dp);
            socket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
public class UDPClientDemo {
    public static void main(String[] args) {
        byte[] bytes = new byte[1024];
        DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
        try {
            DatagramSocket socket = new DatagramSocket(8000);
            System.out.println("正在接受数据");
            socket.receive(dp);
            String s = new String(dp.getData(), 0, dp.getLength());
            System.out.println(s);
            socket.close();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

7 URL

代表一个统一资源定位符,它是指向互联网“资源”的指针。抽象类URLConnection是所有类的超类,他代表应用程序和URL之间的通信链接

public class URLDemo {
    public static void main(String[] args){
        try{

            URL url = new URL("  ");
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            BufferedInputStream in = new BufferedInputStream(conn.getInputStream());
            BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("c:\\yield.jpg"));
            byte[] bytes = new byte[1024];
            int len = -1;
            while((len = in.read(bytes))!= -1){
                out.write(bytes,0,len);
                out.flush();
            }
            in.close();
            out.close();
            System.out.println("下载成功");

        }catch (Exception e){

        }
    }
}

8 MINA 框架

开发一个Mina 应用,简单的说,就是创建连接,设定过滤规则,缩写自己的消息处理器

入门案例

public class Server {
    public static void main(String[] args) {
        // 创建一个非阻塞的Server 端Socket NIO
        SocketAcceptor acceptor = new NioSocketAcceptor();
        DefaultIoFilterChainBuilder chain = acceptor.getFilterChain();
        // 设定一个过滤器, 一行一行的读取数据
//        chain.addLast("name", new ProtocolCodecFilter(new TextLineCodecFactory()));
       // 设定过滤器以对象为单位读取数据
        chain.addLast("objectFilter",new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
        // 设置服务器端的消息处理器
        acceptor.setHandler(new MinaServerHandler());
        int port = 9999;    // 服务器的端口号
        acceptor.setHandler(new MinaServerHandler());
        try {
            // 绑定端口,启动服务器(不会阻塞,立即返回)
            acceptor.bind(new InetSocketAddress(port));
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("Mina Server 已启动");
    }
}
public class MinaServerHandler extends IoHandlerAdapter {

    @Override
    public void sessionOpened(IoSession session) throws Exception {
        super.sessionOpened(session);
        System.out.println("welcome client "+session.getRemoteAddress());
    }

    @Override
    public void sessionClosed(IoSession session) throws Exception {
        super.sessionClosed(session);
        System.out.println("客户端关闭");
    }

    // 接受消息
    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
        super.messageReceived(session, message);
//        String msg = (String) message;
        Message msg = (Message)message;

        System.out.println("收到客户端发来的消息 "+msg);
        msg.setInfo("吃好吃的");
        // 向客户端发送消息对象
        session.write("echo:"+msg);


    }
}
public class Client {
    public static void main(String[] args) {
        // 创建连接
        NioSocketConnector connector = new NioSocketConnector();
        DefaultIoFilterChainBuilder chain = connector.getFilterChain();
//        chain.addLast("myChin", new ProtocolCodecFilter(new TextLineCodecFactory()));
        chain.addLast("objectFilter", new ProtocolCodecFilter(new ObjectSerializationCodecFactory()));
        connector.setHandler(new MinaClientHandler());
        connector.setConnectTimeoutMillis(10000);

        // 连接服务器
        ConnectFuture cf = connector.connect(new InetSocketAddress("localhost", 9999));
        cf.awaitUninterruptibly();
        Scanner input = new Scanner(System.in);
        while (true) {

//            System.out.println("请输入");
//            String info = input.nextLine();
//            cf.getSession().write(info);

            // 以对象的方式传输数据
            Message msg = new Message();
            System.out.println("from:");
            msg.setFrom(input.nextLine());
            System.out.println("to");
            msg.setInfo(input.nextLine());
            System.out.println("info");
            msg.setInfo(input.nextLine());
            msg.setType("send");
            cf.getSession().write(msg);


        }


    }
}
public class MinaClientHandler extends IoHandlerAdapter {
    @Override
    public void sessionOpened(IoSession session) throws Exception {
        super.sessionOpened(session);
        System.out.println(" 客户端连接打开");
    }

    @Override
    public void sessionClosed(IoSession session) throws Exception {
        super.sessionClosed(session);
        System.out.println("客户端连接关闭");
    }

    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {
        super.messageReceived(session, message);
//        String msg = (String) message;
        Message msg = (Message)message;
        System.out.println(msg);
    }
}
public class Message implements Serializable {

    private String from;
    private String to;
    private String type;
    private String info;

    @Override
    public String toString() {
        return "Message{" +
                "from='" + from + '\'' +
                ", to='" + to + '\'' +
                ", type='" + type + '\'' +
                ", info='" + info + '\'' +
                '}';
    }

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值