java基础13 网络编程

来源:互联网 发布:淘宝助理怎么改主图 编辑:程序博客网 时间:2024/05/16 05:31

网络编程

一、网络编程概述

1、网络通讯的3要素是IP地址,端口号和传送协议。

IP地址用以表示网络中的设备,每个设备都有自己唯一的IP地址。本地回环地址是127.0.0.1,同常对应的默认主机名称是localhost192.168.0.0 用于公网  192.168.0.255用于广播

端口号指的是逻辑端口,每个软件在运行时,系统都会分配给它一个未使用的端口号。

端口号的范围是0~65535,通常0~1024用于系统使用或保留端口

       传输协议就是通讯规则,双方发送给对方的数据信息符合指定的传输协议,就可以被对方识别。

如果发送端和接收端安装了共同的网络数据协议,并明确了接收端的IP地址和端口号,就可以将数据发送给接收端。

2、网络参考模型

       OSI参考模型,和TCP/IP参考模型是比较常见的两种网络参考模型。做网络编程,主要涉及的是网际层和传输层。传输层最常见的是TCP和UDP,网际层最常见的是IP,http、ftp是应用层协议。并且应用层基于传输层。

       3、包java.net 用于描述网络

       (1)、包java.net 用于描述网络,其中有操作IP地址的 InetAddress ;有创建UDP服务的 类DatagramSocket,类DatagramPacket 等;有创建TCP服务客户端的 类Socket,服务端的 类ServerSocket操作网页的 类URL

(2)、InetAddress没有可见的构造函数,方法如下

(3)、类DatagramSocket

(4)、类DatagramPacket   

final修饰,构造方法中,只接收字节数组



二、
UDP服务的建立——UDP聊天

1、UDP的特点面向无连接,不可靠,速度快,发送的数据报包大小在64K内

2、建立udp服务端和客户端

* 收和发同时进行,所以收和发在不同的线程中

     键盘录入:键盘录入字节流——>转换字符流——>字符流缓冲区——>循环读取并储存缓冲区的字符——>字节流

    DatagramSocket——2DatagramPacket(传入数据并明确接收端的IP地址和端口)——3发送

注意:

     (1)、因为定义的字节数组是读取的字符转换而来,所以,传入的时候应该传入字节数组的长度

      (2)、另外要注意getByName()的用法

接收

         DatagramSocket(设置端点)>读取发送端发送来的信息——>拆包

     /*本程序已测试,OK*/

    import java.io.*;

import java.net.*;

class UDPChatS implements Runnable {

    private DatagramSocket ds ;

    public UDPChatS(DatagramSocket ds) {

        super();

        this.ds = ds;

    }

    public void run(){

        //读取键盘录入

        BufferedReader br =

                new BufferedReader(new InputStreamReader(System.in));

        try {

            String line = null ;

            //接受键盘录入的数据

            while ((line = br.readLine())!=null) {

                if (line.equals("886"))

                    break ;           

                byte[] buf = line.getBytes();

                //数据封包

                DatagramPacket dp =

                        new DatagramPacket(buf,buf.length, InetAddress.getByName("192.168.0.100"),10060);

                //发送数据包

                ds.send(dp);

            }

        catch (IOException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

        //关闭键盘录入流

        try {

            br.close();

        catch (IOException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

        //关闭服务端

        ds.close();   

    }

}

class UDPChatR implements Runnable{

    private DatagramSocket ds ;

    public UDPChatR(DatagramSocket ds) {

        super();

        this.ds = ds;

    }

    public void run() {

        while(true){

            byte[] buf = new byte[1024];

            DatagramPacket dp = new DatagramPacket(buf, buf.length);

            try {

                ds.receive(dp);

            catch (IOException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

            String data = new String (buf,0,dp.getLength());

            String ip = dp.getAddress().getHostAddress();

            so.p(ip+": "+data);

        }

    }

}

class ChatDemo{

    public static void main(String[] args){   

        DatagramSocket dsSend = null ;

        DatagramSocket dsRece = null;

        try {

            dsSend = new DatagramSocket();

            dsRece = new DatagramSocket(10061);

        catch (SocketException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

        UDPChatR sChatR = new UDPChatR(dsRece);

        UDPChatS sChatS = new UDPChatS(dsSend);

        new Thread(sChatR).start();

        new Thread(sChatS).start();

    }

}

三、TCP服务的建立

1、类Socket 和ServerSocket

       2、tcp传输的特点

              a、面向连接

b、可靠

c、效率稍低

d、建立通路,数据在通路中大量传输

3、TCP并发上传图片

(1)、客户端

a、步骤:图片写到流——> socket流读取流里的图片数据——>发送到服务端

b、客户端代码示例

import java.io.*;

import java.net.*;

import java.util.Date;

class UploadPicC implements Runnable{

    private File file ;

    public UploadPicC(File file) {

        super();

        this.file = file;

    }

    public void run() {

        try {

            OutputStream os = null;

            Socket socket = null ;

            try {

                socket = new Socket("192.168.0.100",10070);

                os = socket.getOutputStream();

            catch (UnknownHostException e1) {

                // TODO Auto-generated catch block

                e1.printStackTrace();

            catch (IOException e1) {

                // TODO Auto-generated catch block

                e1.printStackTrace();

            }

            FileInputStream f = new FileInputStream(file);

            byte[] buf = new byte[1024];

            try {

                int len=0;

                byte[] b = new byte[1024];

                while((len = f.read(buf))!=-1)//这里判断的是-1{

                    os.write(b,0,len);

                }

                socket.shutdownOutput();

            catch (IOException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

//这里要关流,要不然服务端会报异常

            }

            try {

                BufferedReader br =

                        new BufferedReader(new InputStreamReader(socket.getInputStream()));

                String str = br.readLine();

                so.p(str);

            catch (IOException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

        catch (FileNotFoundException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

   

}

(2)、服务端:

建立一个文件写入流——>得到socket的读取流——>利用读流的write方法将数据写到本地

class UploadPicS implements Runnable{

    ServerSocket ss ;

    public UploadPicS(ServerSocket ss) {

        super();

        this.ss = ss;

    }

    public void run() {

        try {

            Socket socket = ss.accept();

            String ip  = socket.getInetAddress().getHostAddress();

            so.p(ip+"......connected");

            FileOutputStream fos = new FileOutputStream("c:\\1_1.jpg");

            InputStream in = socket.getInputStream();

            //向客户端反馈信息

            PrintWriter  pw =

                    new PrintWriter(socket.getOutputStream(),true);

            Date d = new Date();

            byte[] b =new byte[1024];

            int len = 0;

            //循环读取socket输入流中的数据

            while ((len = in.read(b))!=-1) {

                //将数据写到目标文件

                fos.write(b, 0, len);

            }

            so.p(ip+":上传成功");

            pw.write("在    "+d.toString()+"  上传成功");

            pw.close();//要关流  ,要不然客户端会出异常

            fos.close();

        catch (IOException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }

}

class TCP_UploadPic {

    public static void main(String[] args) {

        ServerSocket ss;

        try {

            ss = new  ServerSocket(10070);

            UploadPicS s = new UploadPicS(ss);

            new Thread(s).start();

        catch (IOException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

       

    }

}

4、TCP并发登录

目标:

客户端通过键盘录入用户名

服务端对这个用户名进行校验

如果该用户存在,在服务端显示xxx,已登录

并在客户端显示xxx,欢迎光临

如果该用户存在,在服务端显示xxx,尝试登录

如果客户端显示xxx,该用户不存在

最多登录3次

步骤:

1读取键盘录入

2将键盘录入的信息传入流InputStream

3接收服务端发来的信息

import java.io.*;

import java.net.*;

class LoginC {

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

        Socket s = new Socket("192.168.0.100",10050);

//如果是空“”,是为本机

        //键盘录入流

        BufferedReader bufr = new BufferedReader(

new InputStreamReader(System.in)

);

        //输出流

        PrintWriter out = newPrintWriter(

s.getOutputStream(),true

);

        //得到输入流,

        BufferedReader bufIn = new BufferedReader(

new InputStreamReader(s.getInputStream())

);

        for (int x= 0 ; x <3 ; x++ ){

            //读取键盘录入

            String line  = bufr.readLine();

            /*键盘录入时,按ctrl+c是空,返回-1,说明客户端不想录入了,就结束了*/

            if(line == null)

                break ;

            //将录入内容写入输出流,传到服务端

            out.println(line);

            /*键盘录入时,按ctrl+c是空,out将空发出去了,写入并不能停止,

                那边还在等,所以要做一次判断,如果是空,就结束*/

            //读取服务端传过来的信息

            String info = bufIn.readLine();

            //如果服务端返回的信息包含标记,就跳出循环

            //先打印完服务端返回来的信息,在判断是不是有欢迎

            so.p("info: "+info);

            if(info.contains("欢迎"))

                break ;

        }

        bufr.close();

        s.close();

    }

}

class UserThread implements Runnable{

    private Socket s ;

    UserThread(Socket s)    {

        this.s = s ;

    }

    public void run(){

        // 校验

        String ip = s.getInetAddress().getHostAddress();

        so.p(ip+"......connected");

        try    {

           

            //服务端只校验3次

            for(int x= 0 ; x<3; x++){

                //获取客户端发来的用户名

                BufferedReader bufIn = new BufferedReader(

new InputStreamReader(s.getInputStream())

);

                String name = bufIn.readLine();

                //读一下

                BufferedReader bufr = new BufferedReader(

new FileReader("c:\\数据源.txt")

);

PrintWriter out = new PrintWriter (

s.getOutputStream(),true

);

                String line = null ;

                boolean flag = false ;

                while((line=bufr.readLine())!=null) {

//操作文件时读到结尾返回null

                    if(line.equals(name)){

                        flag = true ;

                        break ;

                    }

                }

                if(flag){

                    so.p(name+",已登录");

                    out.println(name+",欢迎光临");

                    break ;

                }

                else{

                    so.p(name+",尝试登录");

                    out.println(name+",用户名不存在");

//这里不能写成print,否则会报空指针异常

                    so.p(name+",用户名不存在");

                }

            }

            s.close();

        }

        catch (Exception e){

            throw new RuntimeException(ip+"校验失败");

        }

    }

}

class  LoginServer{

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

        ServerSocket ss = new ServerSocket(10050);

        while(true){

            Socket s = ss.accept();

            new Thread(new UserThread(s)).start();

        }

    }

}


原创粉丝点击