Java编程思想 Java网络编程

Java网络编程

Java,有关连网的基层细节被尽可能的提取出去,并隐藏在JVM以及Java的本机安装系统中进行控制。编程模型是一个文件的模型

网络连接(一个套接字)已被封装到系统对象里,可象对其它数据流那样采用同样的方法调用

IP有两种标识:DNS(域名服务),四点格式(由点号分隔的四组数字)

服务器和客户机
服务器

侦听建立连接的请求,由创建的特定服务器对象完成的

客户机

试着与一台服务器建立连接,由创建的特定客户机对象完成的

在没有网络前提下测试程序,特殊的地址localhost

InetAddress addr = InetAddress.getByName(null)

如果向getByName()传递一个null值,默认为使用localhost,

或者

InetAddress addr = InetAddress.getByName("localhost")
InetAddress addr = InetAddress.getByName("127.0.0.1")
端口

一个IP地址不足以完整标识一个服务器

端口编号是必需的二级定址措施

套接字(Socket)

用于表达两台机器间的一个连接的”终端“

Jaa中创建一个套接字,用它建立与其它机器的连接

从套接字得到的结果是一个InputStream以及OutputStream

有两个基于数据流的套接字类:ServerSocket(侦听进入的连接),Scoket(客户用它初始一次连接)

一旦客户申请建立一个套接字连接,ServerSocket返回一个对应的服务器端套接字,进行直接通信

ServerSocket会在主机上创建一个物理性的服务器或者侦听用的套接字

侦听进入的连接,利用accept()方法返回一个已建立套接字

ServerSocket只需赋予一个端口编号

Scoket必须同时赋予IP地址以及要连接的端口编号

简单的服务器和客户机程序
public class JabberServer {
    public static final int PORT = 8080;
    public static void main(String[] args) throws IOException {
        ServerSocket s = new ServerSocket(PORT);
        System.out.println("Started:"+s);
        try{
            //利用accept()方法返回一个已建立套接字
            Socket socket = s.accept();
            try{
                System.out.println("connection accepted:"+socket);
                BufferedReader in = new BufferedReader(
                        new InputStreamReader(
                                socket.getInputStream()));
                //第二个参数布尔值,每次写入输出内容后,它的缓冲区必须刷新,使信息能正式通过网络传递出去,若刷新没有发生,信息不会写入网络,除非缓冲区满
                PrintWriter out = new PrintWriter(
                        new BufferedOutputStream(
                                new OutputStreamWriter(
                                        socket.getOutputStream())),true);
                while(true){
                    String str = in.readLine();
                    if (str.equals("END")) {
                        break;
                    }
                    System.out.println("Encoing:"+str);
                    out.println(str);
            }
        }finally{
            System.out.println("closing...");
            socket.close();
        }
    }finally{
            s.close();
        }

    }
}

报错:‘BufferedOutputStream(java.io.OutputStream)’ in ‘java.io.BufferedOutputStream’ cannot be applied to ‘(java.io.OutputStreamWriter)’

ServerSocket构建器在失败之后不会留下任何打开的网络套接字,无论块以什么方式留下,ServerSocket都能正确的关闭

accept()返回的Socket,如果accept()失败,必须保证Socket不再存在或含有任何资源

套接字使用了重要的非内存资源,必须手动清除

因特网连接用下述四种数据标识:clientHost(客户主机),clientPortNumber(客户端口号),serverHost(服务主机)以及serverPortNumber(服务端口号)

服务程序启动后,会在本地主机上建立为它分配的端口,一旦客户程序发出请求,机器上下一个可用的端口就会分配给它,这一行动也在于服务程序相同的机器上进行。在同一个已知服务程序连接时,客户会发出一个返回地址,使服务程序知道将自己的数据发到哪里

套接字建立了一个专用连接,参与连接的双方都被锁定在通信中,无论是否有数据传递,连接都会持续处于开放状态,为网络带来了额外的开销

服务多个客户

JabberServer每次只能为一个客户程序提供服务

多线程处理机制

方法:在服务器力创建单个ServerSocket,调用accept()来等候一个新连接。一旦accept()返回,取得结果获得的Socket,用它新建一个线程,令其只为特定的客户服务。然后再调用accept(),等候下一次新的连接请求

为一个特定用户提供服务的所有操作移入一个独立的线程

import java.io.*;
import java.net.*;
class ServeoneJabber extends Thread {
    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;
    public ServeoneJabber(Socket s) throws IOException{
        socket = s;
        in = new BufferedReader(
                new InputStreamReader(
                        socket.getInputStream()));
        //自动刷新缓冲
        out = new PrintWriter(
                new BufferedWriter(
                        new OutputStreamWriter(
                                socket.getOutputStream())),true);

        //如果下列任何返回出现错误,自动关闭socket连接
        //ServeoneJabber构建器失败,向调用者掷出一个违例
        //进行线程的初始化
        start();
    }
    @Override
    public void run(){
        try{
            while(true){
                String str = in.readLine();
                if (str.equals("END")){
                    break;
                }
                System.out.println("Echoning: "+str);
                out.println(str);
            }
            System.out.println("closing....");
        }catch(IOException e){

        }finally {
            try{
                //ServeoneJabber构建器成功,由ServeoneJabber对象负责线程的清除
                socket.close();
            }catch(IOException e){

            }
        }
    }
}

/**
 * @author Darlene
 */
public class MultiJabberServer{
    static final int PORT = 8080;
    public static void main(String[] args) throws IOException{
        ServerSocket s = new ServerSocket(PORT);
        System.out.println("Server Started");
        //构建器成功,正确的清除
        try{
            while(true){
                //阻塞直到连接发生
                //允许一个新连接的建立
                Socket socket = s.accept();
                //如果构建器失败,关掉套接字
                try{
                    
                    new ServeoneJabber(socket);
                }catch(IOException e){
                    //如果失败,关闭socket,否则线程会关闭它
                    socket.close();
                }
            }
        }finally {
            s.close();
        }
    }
}

创建许多客户(线程),同相同的服务器建立连接。每个线程存在时间有限,一旦到期,留出空间创建下一个新线程

Socket用于创建某种Reader以及Writer对象,这是运用Socket二点唯一方式,start()执行线程的初始化,调用run().消息发送给服务器,来自服务器的信息在屏幕上回显出来

在套接字创建好以后,在构建器完成之前,假若构建器失败,套接字会被清除,否则,为套接字调用close()

数据报

传输控制协议TCP(基于数据流的套接字),具有高度的可靠性,能保证数据顺利抵达目的地。允许重传走失的数据,收到字节顺序和发出顺序相同。但是具有非常高的开销

用户数据报协议UDP,不可以追求数据包完全发送出去,也不能担保它们抵达的顺序和发出时相同,但是传输速度块

对数据报,在客户和服务器程序都可以防止一个DatagramSocket(数据包套接字),不会和ServerSocket一样等待建立一个连接的请求,陈列出一个数据报。必须直到自己的数据包的来源

DatagramSocket用于收发数据包,DatagramSocket包含了具体的信息,接收数据报使,提供一个缓冲区,安置接收到的数据

可以重复使用数据报的接收代码,缓冲区内的数据都会被覆盖

缓冲区的最大容量仅限于允许的数据报包大小

发出数据报时,DatagramSocket需要包含正式的数据,因特网地址以及端口号

TCP和UDP端口是相互独立的

每个线程都有自己独一无二的标识号

一个Web应用

一部分是在Web服务器上运行的一个java程序,另一部分是一个程序片或小应用程序(Applet),从服务器下载至浏览器。程序篇从用户收集信息,将其传回Web服务器上运行的应用程序

通用网关接口(CGI)程序

服务器应用

NameCollector(名字收集器)

保证多线程不会同时访问文件

使用数据报

一旦监视到有进入的信息,程序进行适当的处理,将答复数据作为一个数据报传回原先发出请求的那名接收者。若数据报在半路丢失,用户可以重新提交请求

Web服务器装备小服务程序或服务程序片(Servlet),负责接收来自客户的请求

Java与CGI的沟通

Java程序可向服务器发出一个CGI请求,这个请求可以设为GET(下载),POST(上传),拦截CGI程序的输出

POST

GET要求通过一个环境变量将自己的数据传递给CGI程序,如果GET字串太长,可以使用POST

POST,数据可以编码,按与GET相同的方法连结起来,POST利用便准输入将编码过后的查询字串传递给CGI程序

用JDBC连接数据库

创建一个数据库URL:用jdbc指出要使用JDBC;子协议:驱动程序的名字或者一种数据库连接机制的名称;数据库标识符

String dbUrl = "jdbc:odbc:people"

如果通过一个网络连接,数据库URL需要包含对远程机器进行标识的信息

准备好同数据库连接后,可调用静态方法DriverManager.getConnection(),将数据库的URL以及进入那个数据库所需的用户名密码传递给它。得到的返回结果是一个Connection对象,查询和操纵数据库

//连接数据库方法
    public static void startConn(){
        try{
           //寻找JDBC驱动程序 Class.forName("com.mysql.jdbc.Driver");
            //连接数据库中间件
            //对配置进行测试
            try{
                连接数据库
                con = DriverManager.getConnection("jdbc:MySQL://localhost:3306/dbtaobao","root","root");
            }catch(SQLException e){
                e.printStackTrace();
            }
        }catch(ClassNotFoundException e){
            e.printStackTrace();
        }
    }

建立自己的查询语句

//数据库双11 所有买家消费行为比例
    public static ArrayList index() throws SQLException{
        ArrayList<String[]> list = new ArrayList();
        startConn();
        stmt = con.createStatement();
        rs = stmt.executeQuery("select action,count(*) num from user_log group by action desc");
        while(rs.next()){
            String[] temp={rs.getString("action"),rs.getString("num")};
            list.add(temp);
        }
            endConn();
        return list;
    }

远程方法

远程方法调用RMI

远程接口

创建一个远程对象是,通过传递一个接口来隐藏基层的实施细节

Servlet Server:因特网服务器应用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值