Java系列(十九)__Java网络编程

Java系列(十九)__Java网络编程


网络编程的时代已经过去了,而且也很难再有新的突破了,所以对于此部分的内容了解一些就够了。如果你不会,也不影响开发。

1.1、网络编程简介

         网络:指的是将物理上分离的计算机通过连接形成的布局,而网络编程指的是实现网络的通讯操作,而在实际的工作之中网络编程分为两类:

· C/S结构(Client / Server):类似于QQ,需要编写两套程序,一套是服务器端程序,另外一套是客户端程序,而在进行维护的时候也需要维护两套程序,C/S使用专署的协议,所以安全性较高;

· B/S结构(Browse/Server):利用浏览器实现客户端功能,开发者只需要开发出服务器端一套程序即可,维护的时候也只需要维护一套程序,B/S结构一般都使用公共的通讯协议(HTTP),所以安全性较差。

         而今天讲解的网络编程主要是以C/S为主进行介绍。而在C/S开发之中也分为两种:TCP(可靠的传输)、UDP(数据报的传输)。今天的内容主要以TCP程序为主,而这个就是Socket程序。

1.2、基本的Socket程序开发

         如果要想开发出Socket程序需要使用java.net包,里面主要使用两操作类完成:

                   · ServerSocket:运行在服务器端,只有通过ServerSocket才可以打开一个监听端口;

· Socket:每一个连接到服务器端的用户都是一个Socket对象,服务器端如果要想操作用户的数据,则必须通过Socket对象取得(输入/输出)。

范例:编写一个服务器端程序

         服务器端主要是ServerSocket服务,在ServerSocket类之中提供有如下方法:

                   · 构造方法:public ServerSocket(int port) throws IOException;

                   · 取得连接:public Socket accept() throws IOException;

         而当服务器端取得了客户端操作之后,就可以向客户端输出信息:

                   · 取得输出流:public OutputStream getOutputStream() throws IOException;

package cn.mldn.demo;

import java.io.PrintStream;

import java.net.ServerSocket;

import java.net.Socket;

public class HelloServer {

    public static void main(String[] args) throws Exception {

        // 在本机的9999端口上进行监听,连接的时候IP地址就是本机地址

        ServerSocket server = new ServerSocket(9999) ;

        System.out.println("服务器端启动.....");

        Socket client = server.accept() ;   // 等待客户端连接

        PrintStream out = new PrintStream(client.getOutputStream()) ;

        out.println("Hello World .") ;

        out.close() ;

        client.close();

        server.close();

    }

}

         本程序只能够处理一个用户的请求,同时只会向客户端发送一次数据,发送完毕之后服务器端就将结束运行。

         运行服务器端之后下面为了测试程序方便,可以直接利用telnet命令进行服务器端的连接操作。这个时候连接到服务器上之后取得服务器上的信息,那么telnet就会被关闭,而此时服务器端也已经关闭了。

         此时的通讯是利用TCP协议实现的连接操作,并且使用的是一个公共工具完成的连接,这样用户将无法进行更多的处理,所以现在可以直接编写一个客户端连接。

范例:编写客户端

         每一个Socket都表示一个客户端连接,所以在Socket类里面存在有以下方法:

                   · 构造方法:public Socket(String host, int port) throws UnknownHostException, IOException;

         但是服务器端的输出数据对客户端而言属于输入数据,所以需要使用Socket类的如下方法取得输入数据:

                   · 取得输入数据:public InputStream getInputStream() throws IOException。

package cn.mldn.demo;

import java.net.Socket;

import java.util.Scanner;

public class HelloClient {

    public static void main(String[] args) throws Exception{

        Socket client = new Socket("192.168.0.253",9999) ;  // 连接服务器端

        Scanner scan = new Scanner(client.getInputStream()) ;

        scan.useDelimiter("\n") ;

        if (scan.hasNext()) {

            System.out.println("服务器端返回数据:" + scan.next());

        }

        scan.close();

        client.close();

    }

}

         这就是一个最基本的网络通讯模型。下面为了方便起见不再重复编写客户端。利用telnet操作。

1.3、网络编程的经典案例 —— Echo程序

       ECHO是现在所有网络编程的基本模型,所谓的ECHO指的是客户端向服务器端发送数据,服务器端接收到数据之后,前面增加一个“ECHO”后返回。

范例:编写服务器端

package cn.mldn.demo;

import java.io.PrintStream;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.Scanner;

public class EchoServer {

    public static void main(String[] args) throws Exception {

        ServerSocket server = new ServerSocket(9999) ;

        Socket client = server.accept() ;   // 连接客户端

        Scanner in = new Scanner(client.getInputStream()) ;

        in.useDelimiter("\n") ;

        PrintStream out = new PrintStream(client.getOutputStream()) ;

        // 如果要想进行无限制的输入,那么可以采用循环的方式进行操作

        boolean flag = true  // 循环标记

        while (flag) {

            if (in.hasNext()) { // 有输入数据

                String data = in.next().trim() ;    // 接收数据

                if ("byebye".equalsIgnoreCase(data)) {  // 结束

                    flag = false // 退出循环

                    out.println("程序结束,拜拜,下次再来!");

                } else   // 前面要增加ECHO返回

                    out.println("ECHO : " + data);

                }

            }

        }

        server.close();

    }

}

         此时的程序只是一个单线程应用,因为只在主线程之中接收用户的请求,那么如果要想让一个服务器可以同时满足于多个用户的使用,则需要将每一个连接到服务器上的用户通过一个新的线程表示。

范例:使用多线程处理多用户访问

package cn.mldn.demo;

import java.io.PrintStream;

import java.net.ServerSocket;

import java.net.Socket;

import java.util.Scanner;

public class EchoServer {

    public static void main(String[] args) throws Exception {

        ServerSocket server = new ServerSocket(9999) ;

        boolean flag = true ;

        while(flag) {   // 循环

            Socket client = server.accept() ;   // 连接客户端

            new Thread(new MyThread(client)).start();

        }

        server.close();

    }

    static class MyThread implements Runnable {

        private Socket client ;

        public MyThread(Socket client) {

            this.client = client ;

        }

        @Override

        public void run() {

            try {

                Scanner in = new Scanner(this.client.getInputStream()) ;

                in.useDelimiter("\n") ;

                PrintStream out = new PrintStream(this.client.getOutputStream()) ;

                // 如果要想进行无限制的输入,那么可以采用循环的方式进行操作

                boolean flag = true  // 循环标记

                while (flag) {

                    if (in.hasNext()) { // 有输入数据

                        String data = in.next().trim() ;    // 接收数据

                        if ("byebye".equalsIgnoreCase(data)) {  // 结束

                            flag = false // 退出循环

                            out.println("程序结束,拜拜,下次再来!");

                        } else   // 前面要增加ECHO返回

                            out.println("ECHO : " + data);

                        }

                    }

                }

                this.client.close();

            } catch (Exception e) {

                e.printStackTrace();

            }

         }}

         此时每一个连接到服务器上的用户都使用一个线程进行处理,从而可以让一个服务器端处理多个客户端的请求。

         所以对于服务器端的开发基本的组成:网络编程 + IO + 多线程,这个概念知道就行了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值