网络编程

来源:互联网 发布:手机挖矿软件 编辑:程序博客网 时间:2024/05/21 19:48

0.IP地址:InetAddress, 网络中设备的标识. 因为不易记忆,可用主机名. 

本地回环地址:127.0.0.1 主机名:localhost. 


1. 端口: 数据要发到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行了标识。为了方便称呼这个数字,叫做端口。(逻辑端口)

有效端口: 0~65535, 其中0~1024被系统使用或者是保留端口. 


2. 协议: 就是通信规则. 常用TCP, UDP


3. OSI参考模型: 


程序员主要在传输层和网际层混. 


4. java.net.InetAddress类示例: 

import java.net.InetAddress;import java.net.UnknownHostException;public class IPDemo {public static void main(String[] args) throws UnknownHostException {InetAddress ia = InetAddress.getByName("www.baidu.com");System.out.println("address:" + ia.getHostAddress());System.out.println("name:" + ia.getHostName());}}

5.* UDP和TCP的区别: 

  • UPD: 1.面向无连接
     2.数据会被封包.在64K内
     3.不可靠,因为无连接.所以不可靠.
     4.速度快,因为不需要连接
     例如.聊天的时候就是UDP的,还有视频会议,桌面共享等.
  • TCP: 1.建立连接,形成传输数据的通道.
     2.在连接中进行大数据量传输
     3.通过三次握手完成连接,是可靠的协议
     4.必须建立连接,但是效率稍低
     例如,打电话就是TCP的.
  • UDP就相当于对讲机,TCP相当于电话. 下载就是TCP的因为不能丢数据.聊天就是UDP的. 

6.* Socket.所谓网络编程, 就是Socket编程. 
  • Socket就是为网络服务提供的一种机制. 
  • 通信的两端都有Socket. 
  • 网络通信其实就是Socket间的通信. 
  • 数据在两个Socket间通过IO传输. 

7. * Upd聊天室例子: 
import java.io.BufferedReader;import java.io.InputStreamReader;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;class Send implements Runnable//发送端{private DatagramSocket ds;public Send(DatagramSocket ds){this.ds = ds;}public void run(){try{BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));String line = null;while((line=bufr.readLine()) != null){if("886".equals(line))//限定条件break;byte[] buf = line.getBytes();//* 封装的时候, 地址"172.0.0.1"如果写成xxx.xxx.xxx.255的话, 局域网里每台机器如果端口对了都能收到. DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("172.0.0.1"), 10002);ds.send(dp);}}catch(Exception e){throw new RuntimeException("发送端失败");}}}class Rece implements Runnable//接收端{private DatagramSocket ds;public Rece(DatagramSocket ds){this.ds = ds;}public void run(){try{while(true){byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf, buf.length);ds.receive(dp);String ip = dp.getAddress().getHostAddress();String data = new String(dp.getData(), 0, dp.getLength());System.out.println(ip+":"+data);}}catch(Exception e){throw new RuntimeException("接收失败");}}}public class ChatDemo {public static void main(String[] args) throws Exception {DatagramSocket sendSocket = new DatagramSocket();DatagramSocket receSocket = new DatagramSocket(10002);new Thread(new Send(sendSocket)).start();new Thread(new Rece(receSocket)).start();}}

8. 使用TCP协议的服务端与客户端的步骤: 
  • 服务端: 
    1. 及案例服务端的socket服务, 并监听一个端口. 
    2. 获取链接过来的客户端对象: 通过ServerSocket的accept方法, 这是个阻塞式方法. 
    3. 客户端如果发过来数据, 服务端要使用对应的客户端对象, 并获取到该客户端对象的读取流来读取发过来的数据. 
    4. 关闭服务(可选). 
  • 客户端: 
    1. 建立socket服务, 指定要连接主机和端口. 
    2. 获取socket流中的输出流, 将数据写到该流中, 通过网络发给服务端. 
    3. 获取socket流中的输入流, 将服务端反馈的数据获取到, 并打印. 

9. 文本转换服务器例子: 
/*需求:建立一个文本转换服务器客户端给服务端发送文本,服务端会将文本转换成大写再返回给客户端而且客户端可以不断的进行文本转换,当客户端输入over时,转换结束分析:    客户端;        既然是操作设备上的数据,那么就可以使用io技术,并按照io的操作规律来思考        源:键盘录入        目的:网络设备,网络输出流        而且操作的是文本数据,可以选择字符流    步骤:        1、建立服务        2、获取键盘录入        3、将数据发给服务端        4、打印出服务端返回的大写数据        5、结束,关资源    都是文本数据,可以使用字符流进行操作,同时提高效率,加入缓冲。    该例子出现的问题,现象:客户端和服务端都在莫名的等待,为什么:因为客户端和服务端都有阻塞式的方法,这些方法都没有读到结束标记,那么就一直等,而导致两端,都在等待        可以使用 PrintWriter PrintReader  ,自动刷新*/import java.net.*;import java.io.*;public class Demo{    public static void main(String[] args) throws Exception{            }    public static void sop(Object obj){        System.out.println(obj);    }}/*客户端1、建立socket服务,指定要连接主机和端口。2、获取socket流中的输出流,将数据写到该流中,通过网络发给服务端。3、获取socket流中的输入流,将服务端反馈的数据获取到,并打印。*/class TransClient{    public static void main(String[] args) throws Exception{        //创建客户端的Socket服务,指定目的主机和端口        Socket s = new Socket("127.0.0.1",10004);                //为了发送数据,应该获取socket流中的输出流        OutputStream out = s.getOutputStream();        //定义读取键盘数据的流对象        BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));        //定义目的,将数据写入到socket输出流,发给服务端        BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));        //定义一个Socket读取流,读取服务端返回的大写信息        BufferedReader bufIn = new BufferedReader(new InputStreamReader(s.getInputStream()));        String line = null;                while((line=bufr.readLine())!=null){            if("over".equals(line)){                break;            }            bufOut.write(line);            bufOut.newLine();            bufOut.flush();            String str = bufIn.readLine();            Demo.sop("server:"+str);        }        bufr.close();        s.close();//当socket调用close时,会发送一个数据-1给服务端,服务器也就结束掉了    }}/*服务端源socket读取流目的,socket'输出流都是文本。装饰*/class TransServer{    public static void main(String[] args) throws Exception{        //建立服务端socket服务,并监听一个端口        ServerSocket ss = new ServerSocket(10004);        //通过accept方法获取链接过来的客户端对象        Socket s = ss.accept();        Demo.sop(s.getInetAddress().getHostAddress()+"  已接入");        //读取socket读取流中数据        BufferedReader bufIn= new BufferedReader(new InputStreamReader(s.getInputStream()));        //目的,socket输出流,将大写数据写入到socket输出流,并发送给客户端        BufferedWriter bufOut = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));        String line= null;        Demo.sop("等待接受数据。。。");        while((line=bufIn.readLine())!=null){//根据readLine()判断回车符,来判断结束            bufOut.write(line.toUpperCase());            bufOut.newLine();//这是结束标记            bufOut.flush();//缓冲区        }        s.close();        ss.close();    }}

10. 上传图片的小栗子: 
import java.io.*;import java.net.*;class PicClient{public static void main(String[] args) throws Exception{Socket s = new Socket("127.0.0.1", 10007);FileInputStream fis = new FileInputStream("1.bmp");OutputStream out = s.getOutputStream();byte[] buf = new byte[1024];int len = 0;while((len=fis.read(buf)) != -1){out.write(buf, 0, len);}//告诉服务端数据已经写完s.shutdownOutput();InputStream in = s.getInputStream();byte[] bufIn = new byte[1024];int num = in.read(bufIn);System.out.println(new String(bufIn, 0, num));fis.close();s.close();}}class PicServer{public static void main(String[] args) throws Exception{ServerSocket ss = new ServerSocket(10007);Socket s = ss.accept(); InputStream in = s.getInputStream();FileOutputStream fos = new FileOutputStream("server.bmp");byte[] buf = new byte[1024];int len = 0;while((len=in.read(buf)) != -1){fos.write(buf, 0, len);}OutputStream out = s.getOutputStream();out.write("上传成功".getBytes());fos.close();s.close();ss.close();}}public class UploadPic {public static void main(String[] args) {}}

11. 客户端并发上传图片例子: 
import java.io.*;import java.net.*;public class Demo{    public static void main(String[] args){            }}class PicClient{    public static void main(String[] args) throws Exception{        if(args.length!=1){            System.out.println("请选择一个jpg格式的图片");            return;        }        File file = new File(args[0]);        if(!(file.exists()&&file.isFile())){            System.out.println("该文件有问题,要么不存在,要不不是文件");            return;        }        if(!file.getName().endsWith(".jpg")){            System.out.println("图片格式错误,请重新选择jpg");            return;        }        if(file.length()>1024*1024){            System.out.println("图片过大");            return;        }        Socket s = new Socket("127.0.0.1",10007);        FileInputStream fis = new FileInputStream(file);        OutputStream out = s.getOutputStream();        byte[] buf = new byte[1024];        int len = 0;        while((len=fis.read(buf))!=-1){            out.write(buf,0,len);        }        s.shutdownOutput();        InputStream in = s.getInputStream();        byte[] bufIn = new byte[1024];        int num = in.read(bufIn);         System.out.println(new String(bufIn,0,num));        fis.close();        s.close();    }}/*服务端:这个服务端有个局限性。当a客户端连接上后,被服务端获取到,服务段执行具体流程,、b客户端只有等待,因为服务端 还没有处理完a客户端的请求,还有循环回来执行下次accept方法,所以暂时获取不到b客户端对象那么为了可以让多个客户端同时并发访问服务端那么服务端最好是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求如何定义线程呢?只要明确了每一个客户端要在服务端执行的代码即可,将该代码存入到run方法中*/class PicThread implements Runnable{    private Socket s;    PicThread(Socket s){        this.s = s;    }    public void run(){        String ip = s.getInetAddress().getHostAddress();        try{            int count = 1;            System.out.println(ip+".....conneted");            InputStream in = s.getInputStream();                                    File file = new File(ip+".jpg");                        while(file.exists()){                file = new File(ip+"("+(count++)+").jpg");            }                        FileOutputStream fos = new FileOutputStream(file);            byte[] buf = new byte[1024];            int len = 0;            while((len=in.read(buf))!=-1){                fos.write(buf,0,len);            }            OutputStream out = s.getOutputStream();            out.write("上传成功".getBytes());            System.out.println(ip+".....success");            fos.close();            s.close();        }catch(Exception e){            throw new RuntimeException("上传失败");        }    } }class PicServer{    public static void main(String[] args) throws Exception{        ServerSocket ss = new ServerSocket(10007);        while(true){            Socket s = ss.accept();            new Thread(new PicThread(s)).start();        }        //ss.close();    }}

12. URL和URLConnection类: 提供了更多对URL的操作. 

  • 构造器: 
    URL(String spec)  根据 String 表示形式创建 URL 对象。 
    URL(String protocol, String host, int port, String file)  根据指定 protocol、host、port 号和 file 创建 URL 对象。 
  • 方法: 
    Object getContent()  获取此 URL 的内容。
    Object getContent(Class[] classes)  获取此 URL 的内容。
    int getDefaultPort()  获取与此 URL 关联协议的默认端口号。
    String getFile()   获取此 URL 的文件名。 
    String getHost()  获取此 URL 的主机名(如果适用)。 
    String getPath()  获取此 URL 的路径部分。 
    int getPort()  获取此 URL 的端口号。 
    String getProtocol()  获取此 URL 的协议名称。 
    String getQuery()  获取此 URL 的查询部分。
  • 示例: 
    import java.io.*;import java.net.*;public class Demo{    public static void main(String[] args) throws Exception{        URL url = new URL("http://127.0.0.1:8080/myweb/index.html?a=1&b=2");        sop("getDefaultPort() :"+url.getDefaultPort());//getDefaultPort() :80        sop("getFile() :"+url.getFile());//getFile() :/myweb/index.html        sop("getHost() :"+url.getHost());//getHost() :127.0.0.1        sop("getPath() :"+url.getPath());//getPath() :/myweb/index.html        sop("getPort() :"+url.getPort());//getPort() :8080,如果没有填,则获取的时候,会返回-1,可以判断是否为-1,给他一个端口号        sop("getProtocol() :"+url.getProtocol());//getProtocol() :http        sop("getQuery() :"+url.getQuery());//getQuery() :a=1&b=2    }    public static void sop(Object obj){        System.out.println(obj);    }}/*URLConnection openConnection() 返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接。 */import java.io.*;import java.net.*;public class Demo{    public static void main(String[] args) throws Exception{        URL url = new URL("http://127.0.0.1:8080/myweb/index.html");        URLConnection conn = url.openConnection();        InputStream in = conn.getInputStream();        BufferedReader br = new BufferedReader(new InputStreamReader(in,"utf-8"));         String line = null;        while((line = br.readLine())!=null){            sop(line);        }    }    public static void sop(Object obj){        System.out.println(obj);    }}



原创粉丝点击