网络编程

概述

现在的网络编程基本上都是基于请求/响应方式的,也就是一个设备发送请求数据给另外一个,然后接收另一个设备的反馈

在网络编程中,发起连接程序,也就是发送第一次请求的程序,被称作客户端(Client),等待其他程序连接的程序被称作服务器(Server)。

网络通信协议

连接和通信的规则被称为网络通信协议,它对数据的传输格式、传输速率、传输步骤等做了统一规定,通信双方必须同时遵守才能完成数据交换

IP地址和端口号

IP地址:InetAddress
        网络中设备的标识
        不易记忆,可用主机名
        本地回环地址:127.0.0.1  主机名:localhost
    端口号
        用于标识进程的逻辑地址,不同进程的标识。逻辑地址,区分不同的服务
        有效端口:0~65535,其中0~1024系统使用或保留端口。
        备注:不是所谓的物理端口!

InetAddress

InetAddress:构造方法私有,不能直接创建对象。

InetAddress getByName(String host):
在给定主机名的情况下确定主机的ip地址。

InetAddress getLocalHost():返回本地主机。

InetAddress[] getAllByName(String host);

ip.getHostAddress()

ip.getHostName()

Eg:
package com.li.net;
import java.net.InetAddress;

public class Demo1 {
    public static void main(String[] args) throws Exception {
        InetAddress i = InetAddress.getLocalHost();
        System.out.println(i);
        i = InetAddress.getByName("www.baidu.com");
        System.out.println(i);
        System.out.println(i.getHostAddress());
        System.out.println(i.getHostName());
    }
}
输出:
XP-201706252326/10.6.147.2
www.baidu.com/61.135.169.105
61.135.169.105
www.baidu.com

UDP与TCP协议

TCP/IP协议(Transmission Control Protocal/Internet Protoal传输控制协议/英特网互联协议),它是一个包括TCP协议和IP协议。
UDP(User Datagram Protocol)用户数据报协议
ICMP(Internet Control Message Protocol)协议和其它一些协议的协议组

区别

类似于图像、声音等对可靠性要求没有那么高的业务可以用UDP,他们不需要准确存储对准确性无要求但要求速度快

类似于文本、程序、文件等要求可靠的数据最好就用TCP,但会牺牲一些速度。 
对系统资源的要求:TCP较多,UDP少。 
程序结构:UDP程序结构较简单,TCP复杂。 
流模式与数据报模式:TCP保证数据正确性,UDP可能丢包; TCP保证数据顺序,UDP不保证

用途

TCP是面向连接的,有比较高的可靠性,一些要求比较高的服务一般使用这个协议,如FTP、Telnet、SMTP、HTTP、POP3等,而 UDP是面向无连接的,使用这个协议的常见服务有DNS、SNMP、QQ等。

UDP是一种面向无连接的通信协议,该协议使得数据传输的速度得到大幅度的提高。视频聊天语音聊天基本都是用UDP协议。

总结

UDP:

1、将数据源和目的地封装到数据包中,不需要建立连接

2、每个数据包的大小限制在64k以内

3、因无连接,是不可靠协议

4、不需要建立连接,速度快

例子:聊天、对讲机就是UDP的,面向无连接(不管在不在,知不知道,只管发送,求速度),丢数据也不管。速度快。数据被分成包

TCP:

1、建立连接,形成传输数据的通道

2、在连接中进行大量数据的传输

3、通过三次握手完成连接、是可靠协议

4、必须建立连接,效率会稍低

例子:电话通话,必须连接,对方同意才可以发送数据(不然就等待),不能丢失数据。

UDP通信

DatagramPacket

DatagramPacket类的实例对象就相当于一个集装箱,用于封装UDP通信中发送或者接收的数据

通过这个对象中的方法,就可以获取到数据包中的各种信息
    byte[] getData()

int getLength()

int getPort()

setData(byte[]

setPort()

DatagramSocket

DatagramSocket类的作用就类似于码头,使用这个类的实例对象就可以发送和接收DatagramPacket数据包,封装了udp传输协议的socket对象
具备发送和接受功能,在进行udp传输时,需要明确一个是发送端,一个是接收端。

receive(DatagramPacket)

send(DatagramPacket)

UDP网络编程

udp的发送端

①:建立udp的socket服务,创建对象时如果没有明确端口,系统会自动分配一个未被使用的端口。

②:明确要发送的具体数据。

③:将数据封装成了数据包。

④:用socket服务的send方法将数据包发送出去。

⑤:关闭资源。

发送端(客户端)
import java.net.*;
class  UdpSend {
     public static void main(String[] args)throws Exception {
           // 1,建立udp的socket服务。
           DatagramSocket ds = new DatagramSocket(8888);//指定发送端口,这个可以不指定,系统会随机分配。
            // 2,明确要发送的具体数据。
            String text = "udp传输演示 哥们来了";
            byte[] buf = text.getBytes();
             // 3,将数据封装成了数据包。
             DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("10.1.31.127"),10000);
             // 4,用socket服务的send方法将数据包发送出去。
             ds.send(dp);
             // 5,关闭资源。
             ds.close();
     }
}

udp的接收端

①:创建udp的socket服务,必须要明确一个端口,作用在于,只有发送到这个端口的数据才是这个接收端可以处理的数据。

②:定义数据包,用于存储接收到数据。

③:通过socket服务的接收方法将收到的数据存储到数据包中。

④:通过数据包的方法获取数据包中的具体数据内容,比如ip、端口、数据等等。

⑤:关闭资源。

接收端(服务器端)

import java.net.*;
class UdpRece {
     public static void main(String[] args) throws Exception {
           // 1,创建udp的socket服务。
           DatagramSocket ds = new DatagramSocket(10000);
//必须指定,并且和上面的端口号一样!
           // 2,定义数据包,用于存储接收到数据。先定义字节数组,数据包会把数据存储到字节数组中。
           byte[] buf = new byte[1024];
           DatagramPacket dp = new DatagramPacket(buf,buf.length);
           // 3,通过socket服务的接收方法将收到的数据存储到数据包中。
           ds.receive(dp); //该方法是阻塞式方法。
           // 4,通过数据包的方法获取数据包中的具体数据内容,比如ip,端口,数据等等。
           String ip = dp.getAddress().getHostAddress();
           int port = dp.getPort();
           String text = new String(dp.getData(),0,dp.getLength());
//将字节数组中的有效部分转成字符串。
           System.out.println(ip+":"+port+"--"+text);
           // 5,关闭资源。
           ds.close();
    }

}

UDP案例--聊天程序

通过键盘录入获取要发送的信息。

将发送和接收分别封装到两个线程中。

  1. package com.li.net;
  2. import java.io.BufferedReader;
  3. import java.io.IOException;
  4. import java.io.InputStreamReader;
  5. import java.net.DatagramPacket;
  6. import java.net.DatagramSocket;
  7. import java.net.InetAddress;
  8. //客户端,发送端
  9. class Send implements Runnable {
  10. private DatagramSocket ds;
  11. public Send(DatagramSocket ds) {
  12. super();
  13. this.ds = ds;
  14. }
  15. @Override
  16. public void run() {
  17. try {
  18. BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//数据源是键盘录入
  19. String line;
  20. while ((line = br.readLine()) != null) {
  21. byte[] buf = line.getBytes();
  22. DatagramPacket dp = new DatagramPacket(buf, buf.length,InetAddress.getByName("localhost"), 10225);
  23. ds.send(dp);
  24. }
  25. } catch (IOException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. }
  30. // 服务器端,接收端
  31. class Rece implements Runnable {
  32. private DatagramSocket ds;
  33. public Rece(DatagramSocket ds) {
  34. super();
  35. this.ds = ds;
  36. }
  37. @Override
  38. public void run() {
  39. try {
  40. while (true) {
  41. byte[] buf = new byte[1024];
  42. DatagramPacket dp = new DatagramPacket(buf, 0, buf.length);
  43. ds.receive(dp);
  44. String ip = dp.getAddress().getHostAddress();
  45. String data = new String(dp.getData(), 0, dp.getLength());
  46. System.out.println(ip + " " + data);
  47. }
  48. } catch (Exception e) {
  49. e.printStackTrace();
  50. }
  51. }
  52. }
  53. public class Demo6 {
  54. public static void main(String[] args) throws Exception {
  55. DatagramSocket sendDs = new DatagramSocket();
  56. DatagramSocket receDs = new DatagramSocket(10225);
  57. new Thread(new Send(sendDs)).start();
  58. new Thread(new Rece(receDs)).start();
  59. }
  60. }
  61. 输出:
  62. 你好
  63. 127.0.0.1 你好
  64. 你好
  65. 127.0.0.1 你好

TCP通信

TCP通信是严格区分客户端与服务器端的,在通信时,必须先由客户端去连接服务器端才能实现通信,服务器端不可以主动连接客户端,并且服务器端程序需要事先启动,等待客户端的连接

在JDK中提供了两个类用于实现TCP程序,一个是ServerSocket类,用于表示服务器端,一个是Socket类,用于表示客户端

ServerSocket

ServerSocket(端口) - 构造器

setSoTimeout(int)

Socket accept()

close()

Socket

Socket就是为网络服务提供的一种机制。

Socket(IP地址, 端口) - 构造器

getInputStream()

getOutputStream()

getChannel()

close()

TCP案例--文件上传

题目:上传文件,多客户端上传,并且保证不会因为文件的名称而重复!
客户端:

  1. package com.li.net;
  2. import java.io.BufferedReader;
  3. import java.io.FileReader;
  4. import java.io.InputStreamReader;
  5. import java.io.PrintWriter;
  6. import java.net.Socket;
  7.  
  8. public class Demo22 {
  9. public static void main(String[] args) throws Exception {
  10. Socket s = new Socket("localhost", 12036);
  11. BufferedReader br = new BufferedReader(new FileReader("E:/你好.txt"));
  12. PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
  13. BufferedReader br2 = new BufferedReader(new InputStreamReader(s.getInputStream()));
  14. String line;
  15. while((line = br.readLine()) != null) {
  16. pw.println(line);
  17. }
  18. s.shutdownOutput();
  19. String str = br2.readLine();
  20. System.out.println(str);
  21. s.close();
  22. }
  23. }

服务器端:

  1. package com.li.net;
  2. import java.io.BufferedReader;
  3. import java.io.File;
  4. import java.io.FileWriter;
  5. import java.io.InputStreamReader;
  6. import java.io.PrintWriter;
  7. import java.net.ServerSocket;
  8. import java.net.Socket;
  9.  
  10. class MyUpdate implements Runnable {
  11. private Socket s;
  12. public MyUpdate(Socket s) {
  13. super();
  14. this.s = s;
  15. }
  16. @Override
  17. public void run() {
  18. String ip = s.getInetAddress().getHostAddress();
  19. System.out.println(ip+".........connected!");
  20. int count = 0;
  21. try {
  22. BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
  23. File file = new File("E:/");
  24. File f = new File(file,"你好"+count+".txt");
  25. while(f.exists()) { //如果写成if,就不可以!
  26. f = new File(file,"你好"+(++count)+".txt");
  27. }
  28. PrintWriter pw = new PrintWriter(new FileWriter(f),true);
  29. PrintWriter pw2 = new PrintWriter(s.getOutputStream(),true);
  30. String line;
  31. while((line = br.readLine()) != null) {
  32. pw.println(line);
  33. }
  34. pw2.println("恭喜您,上传成功!");
  35. s.close();
  36. } catch (Exception e) {
  37. e.printStackTrace();
  38. }
  39. }
  40. }
  41. public class Demo23 {
  42. public static void main(String[] args) throws Exception {
  43. ServerSocket ss = new ServerSocket(12036);
  44. while(true) {
  45. Socket s = ss.accept();
  46. new Thread(new MyUpdate(s)).start();
  47. }
  48. }
  49. }

Java精选笔记_网络编程的更多相关文章

  1. Java精选笔记_面向对象(包、访问控制、内存机制、垃圾回收机制)

    包 包的定义与使用 专门用来存放类的,通常功能相同的类存放在相同的包中. 包的声明只能位于Java源文件的第一行 Java语言中的常用包 java.lang:包含Java语言的核心类,如String. ...

  2. Java精选笔记_自定义标签

    自定义标签 自定义标签入门 什么是自定义标签 自定义标签可以有效地将HTML代码与Java代码分离,从而使不懂Java编程的HTML设计人员也可以编写出功能强大的JSP页面 JSP规范中定义了多个用于 ...

  3. Java精选笔记_多线程(创建、生命周期及状态转换、调度、同步、通信)

    线程概述 在应用程序中,不同的程序块是可以同时运行的,这种多个程序块同时运行的现象被称作并发执行. 多线程可以使程序在同一时间内完成很多操作. 多线程就是指一个应用程序中有多条并发执行的线索,每条线索 ...

  4. Java精选笔记_面向对象(多态、异常)

    多态 概述 可以理解为事物存在的多种体现形态.同样的引用调用同样的方法却做了不同的事情 多态的本质是:一个程序中同名的不同方法. 多态的体现 父类的引用指向子类的对象,父类的引用接收子类的对象. 多态 ...

  5. Java精选笔记_面向对象(构造方法、this关键字、static关键字、内部类)

    构造方法constructor构造器 构造方法的定义 [修饰符]  类名 (形式参数列表){         //语句 } 构造器用于构造该类的实例.作用:用来初始化对象!一般由系统在创建对象(即类的 ...

  6. Java精选笔记_面向对象(慨念、类和对象)

    面向对象概念 在程序中使用对象来映射现实中的事物,使用对象的关系来描述事物之间的联系,这种思想就是面向对象. 相对于面向过程而言.是一种思想,强调的是功能的对象. 面向对象的本质:以类的方式组织代码, ...

  7. Java精选笔记_国际化

    国际化 什么是国际化 指软件在开发时就应该具备支持多种语言和地区的功能,当应对不同国家和地区的用户访问,针对不同国家和地区的用户,提供相应的.符合来访者阅读习惯的页面和数据. 由于国际化interna ...

  8. Java精选笔记_文件上传与下载

    文件上传与下载 如何实现文件上传 在Web应用中,由于大多数文件的上传都是通过表单的形式提交给服务器的,因此,要想在程序中实现文件上传的功能,首先得创建一个用于提交上传文件的表单页面. 为了使Serv ...

  9. Java精选笔记_会话技术

    会话及其会话技术 会话概述 指的是一个客户端(浏览器)与Web服务器之间连续发生的一系列请求和响应过程. 会话:从浏览器开启到浏览器关闭.会话技术:用来保存在会话期间 浏览器和服务器所产生的数据. 在 ...

随机推荐

  1. LeetCode: Combination Sum 解题报告

    Combination Sum Combination Sum Total Accepted: 25850 Total Submissions: 96391 My Submissions Questi ...

  2. mysql status

    要查看MySQL运行状态,要优化MySQL运行效率都少不了要运行show status查看各种状态,下面是参考官方文档及网上资料整理出来的中文详细解释: 状态名 作用域 详细解释 Aborted_cl ...

  3. c++多态之——vptr指针

    之前做过一个测试,在一个类中定义一个virtual修饰的函数时,sizeof这个类,发现类的大小多了恰好一个指针的字节大小,当初不明白,只是记住有这么一个特性.后来,发现它就是c++编译器给我们添加的 ...

  4. c++之拷贝构造函数调用时机

    test1: #include<iostream> using namespace std; class Copy_construction { public: Copy_construc ...

  5. iOS键盘类型以及样式展示

    UIKeyboardTypeDefault: UIKeyboardTypeASCIICapable: UIKeyboardTypeNumbersAndPunctuation: UIKeyboardTy ...

  6. MFC和GTK的区别

    关键技术 http://blog.csdn.net/master_max/article/details/1540204 MFC和GTK的区别?? 1. 两者都是基于面向对象设计的.尽管MFC是用C+ ...

  7. Ajax初窥

    Ajax四个步骤 1. 创建Ajax对象2. 连接到服务器3. 发送请求4. 接收返回值 0x01 创建AJAX对象 方法1(非IE6.0) Var oAjax = new XMLHttpReques ...

  8. 在chrome中的source找不到自己写的js时处理方法

    今天准备调试下js,突然发现在谷歌的中source中找不到我要调试的js,后来查资料和听同事说谷歌会把js压缩,于是找到以下方法来调试js 1. debugger神器 横扫各个浏览器.脚本运行到deb ...

  9. 【C#/WPF】调节图像的HSL(色相Hue、饱和度Saturation、明亮度Lightness)

    先说概念: HSL是一种描述颜色的方式,其他颜色描述方式还有大家熟悉的RGB值.HSL三个字母分别表示图像的Hue色相.Saturation饱和度.Lightness明亮度. 需求: 制作一个面板,包 ...

  10. 求链表倒数第k个节点

    程序员面试题6-查找链表中倒数第k个结点 (-- ::)转载▼ 标签: 杂谈 分类: 程序设计 题目:输入一个单向链表,输出该链表中倒数第k个结点.链表的倒数第0个结点为链表的尾指针.链表结点定义如下 ...