提供的网络类库,可以实现无痛的网络连接,联网的底层细节被隐藏在 Java 的本机安装系统里,由 JVM 进行控制。并且 Java 实现了一个跨平台的网络库,程序员面对的是一个统一的网络编程环境。
网络中的主机相互通信必须解决:
1、通信双方地址 2、一定的规则: OSI参考模型:模型过于理想化,未能在因特网上进行广泛推广 TCP/IP参考模型(或TCP/IP协议):事实上的国际标准。网络通信协议
通讯要素1:IP 和 端口号
- IP 地址:InetAddress 唯一的标识 Internet 上的计算机 本地回环地址(hostAddress):127.0.0.1 主机名(hostName):localhost
- 端口号标识正在计算机上运行的进程(程序) 不同的进程有不同的端口号 被规定为一个 16 位的整数 0~65535。其中,0~1023被预先定义的服务通信占用(如MySql占用端口3306,http占用端口80等)。除非我们需要访问这些特定服务,否则,就应该使用 1024~65535 这些端口中的某一个进行通信,以免发生端口冲突。
- 端口号与IP地址的组合得出一个网络套接字。
/* * 网络通信的第一个要素:IP地址。通过IP地址,唯一的定位互联网上一台主机 * InetAddress:位于java.net包下 * 1.InetAddress用来代表IP地址。一个InetAdress的对象就代表着一个IP地址 * 2.如何创建InetAddress的对象:getByName(String host) * 3.getHostName(): 获取IP地址对应的域名 * getHostAddress():获取IP地址 */public class TestInetAddress { public static void main(String[] args) throws Exception { //创建一个InetAddress对象:getByName() InetAddress inet = InetAddress.getByName("www.atguigu.com"); //inet = InetAddress.getByName("42.121.6.2"); System.out.println(inet); //两个方法 System.out.println(inet.getHostName()); System.out.println(inet.getHostAddress()); //获取本机的IP:getLocalHost() InetAddress inet1 = InetAddress.getLocalHost(); System.out.println(inet1); System.out.println(inet1.getHostName()); System.out.println(inet1.getHostAddress()); }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
通讯要素2:网络通信协议
- TCP协议,传输控制协议(Transmission Control Protocol): 使用TCP协议前,须先建立TCP连接,形成传输数据通道 传输前,采用“三次握手”方式,是可靠的 TCP协议进行通信的两个应用进程:客户端、服务端 在连接中可进行大数据量的传输 传输完毕,需释放已建立的连接,效率低
- UDP协议,用户数据报协议(User Datagram Protocol): 将数据、源、目的封装成数据包,不需要建立连接 每个数据报的大小限制在64K内 因无需连接,故是不可靠的 发送数据结束时无需释放资源,速度快
Socket
基于TCP的Socket通信
Socket类的常用方法
ServerSocket类的常用方法
练习:
//1.服务端读取图片并发送给客户端,客户端保存图片到本地public class TestTcp { @Test public void client(){ Socket socket=null; OutputStream os=null; FileInputStream fis=null; InputStream is=null; try { //1.创建Socket的对象 socket = new Socket(InetAddress.getByName("127.0.0.1"), 9898); //2.从本地获取一个文件发送给服务端 os = socket.getOutputStream(); fis = new FileInputStream(new File("1.jpg")); byte[] b = new byte[1024]; int len; while((len = fis.read(b)) != -1){ os.write(b,0,len); } socket.shutdownOutput();//显式的告诉服务端发送完毕! //3.接收来自于服务端的信息 is = socket.getInputStream(); byte[] b1 = new byte[1024]; int len1; while((len1 = is.read(b1)) != -1){ String str = new String(b1,0,len1); System.out.print(str); } }catch (IOException e) { e.printStackTrace(); }finally{ //4.关闭相应的流和Socket对象 if(is!=null){ try { is.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(os!=null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if(fis!=null){ try { fis.close(); } catch (IOException e) { e.printStackTrace(); } }if(socket!=null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test public void server(){ ServerSocket ss=null; Socket s=null; InputStream is=null; FileOutputStream fos=null; OutputStream os=null; try { //1.创建一个ServerSocket的对象 ss = new ServerSocket(9898); //2.调用其accept()方法,返回一个Socket的对象 s = ss.accept(); //3.将从客户端发送来的信息保存到本地 is = s.getInputStream(); fos = new FileOutputStream(new File("3.jpg")); byte[] b = new byte[1024]; int len; while((len = is.read(b)) != -1){ fos.write(b, 0, len); } System.out.println("收到来自于" + s.getInetAddress().getHostAddress() + "的文件"); //4.发送"接收成功"的信息反馈给客户端 os = s.getOutputStream(); os.write("你发送的图片我已接收成功!".getBytes()); } catch (IOException e) { e.printStackTrace(); }finally{ //5.关闭相应的流和Socket及ServerSocket的对象 if(os!=null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if(fos!=null){ try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } if(is!=null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if(s!=null){ try { s.close(); } catch (IOException e) { e.printStackTrace(); } } if(ss!=null){ try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } } }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
//客户端给服务端发送文本,服务端会将文本转成大写在返回给客户端。//如下程序为了保证相应的流及socket的关闭(即使在关闭之前出现异常,也一定要保证相应的资源的关闭),要求是用//try-catch-finally进行操作。要求将关闭的信息写在finally里!public class TestTCP { @Test public void client() { // 1. Socket socket = null; // 2. OutputStream os = null; Scanner scanner = null; // 4.接收来自于服务端的数据 InputStream is = null; try { socket = new Socket(InetAddress.getByName("127.0.0.1"), 9090); os = socket.getOutputStream(); // 3.向服务端发送数据 // os.write("abc".getBytes()); System.out.println("请输入多个字符:"); scanner = new Scanner(System.in); String str = scanner.next(); os.write(str.getBytes()); socket.shutdownOutput(); is = socket.getInputStream(); byte[] b = new byte[10]; int len; while ((len = is.read(b)) != -1) { String str1 = new String(b, 0, len); System.out.print(str1); } } catch (IOException e) { e.printStackTrace(); } finally { // 5. if(is != null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if(scanner != null){ scanner.close(); } if(os != null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if(socket != null){ try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test public void server() { // 1. ServerSocket ss = null; // 2. Socket s = null; // 3.接收来自于客户端的信息 InputStream is = null; // 4.返回给客户端 OutputStream os = null; try { ss = new ServerSocket(9090); s = ss.accept(); is = s.getInputStream(); byte[] b = new byte[10]; int len; String str = new String(); while ((len = is.read(b)) != -1) { String str1 = new String(b, 0, len); str += str1; } String strUpperCase = str.toUpperCase(); os = s.getOutputStream(); os.write(strUpperCase.getBytes()); } catch (IOException e) { e.printStackTrace(); }finally{ if(os != null){ try { os.close(); } catch (IOException e) { e.printStackTrace(); } } if(is != null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); } } if(s != null){ try { s.close(); } catch (IOException e) { e.printStackTrace(); } } if(ss != null){ try { ss.close(); } catch (IOException e) { e.printStackTrace(); } } } // 5. }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
UDP网络通信
- 类 DatagramSocket 和 DatagramPacket 实现了基于 UDP 协议网络程序。
- UDP数据报通过数据报套接字 DatagramSocket 发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。
- DatagramPacket 对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号。
- UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接
//UDP编程的实现public class TestUDP { // 发送端 @Test public void send() { DatagramSocket ds = null; try { ds = new DatagramSocket(); byte[] b = "你好,我是要发送的数据".getBytes(); //创建一个数据报:每一个数据报不能大于64k,都记录着数据信息,发送端的IP、端口号,以及要发送到 //的接收端的IP、端口号。 DatagramPacket pack = new DatagramPacket(b, 0, b.length, InetAddress.getByName("127.0.0.1"), 9090); ds.send(pack); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(ds != null){ ds.close(); } } } // 接收端 @Test public void rceive() { DatagramSocket ds = null; try { ds = new DatagramSocket(9090); byte[] b = new byte[1024]; DatagramPacket pack = new DatagramPacket(b, 0, b.length); ds.receive(pack); String str = new String(pack.getData(), 0, pack.getLength()); System.out.println(str); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(ds != null){ ds.close(); } } }}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
URL编程
URL(Uniform Resource Locator):统一资源定位符,它表示 Internet 上某一资源的地址。浏览器通过解析给定的 URL 可以在网络上查找相应的文件或其他资源。
URL的基本结构由5部分组成:
<传输协议>://<主机名>:<端口号>/<文件名> 例如:一个URL对象生成后,其属性是不能被改变的,但可以通过它给定的方法来获取这些属性:
public String getProtocol( ) 获取该URL的协议名 public String getHost( ) 获取该URL的主机名 public String getPort( ) 获取该URL的端口号 public String getPath( ) 获取该URL的文件路径 public String getFile( ) 获取该URL的文件名 public String getRef( ) 获取该URL在文件中的相对位置 public String getQuery( ) 获取该URL的查询名URL的方法 openStream():能从网络上读取数据
若希望输出数据,例如向服务器端的 CGI (公共网关接口-Common Gateway Interface-的简称,是用户浏览器和服务器端的应用程序进行连接的接口)程序发送一些数据,则必须先与URL建立连接,然后才能对其进行读写,此时需要使用 URLConnection 。 URLConnection:表示到URL所引用的远程对象的连接。当与一个URL建立连接时,首先要在一个 URL 对象上通过方法 openConnection() 生成对应的 URLConnection 对象。如果连接过程失败,将产生IOException. URL netchinaren = new URL (““); URLConnectonn u = netchinaren.openConnection( );通过URLConnection对象获取的输入流和输出流,即可以与现有的CGI程序进行交互。
public Object getContent( ) throws IOException public int getContentLength( ) public String getContentType( ) public long getDate( ) public long getLastModified( ) public InputStream getInputStream( )throws IOException public OutputSteram getOutputStream( )throws IOExceptionpublic class TestURL { public static void main(String[] args) throws Exception { //1.创建一个URL的对象 URL url = new URL("http://127.0.0.1:8080/examples/HelloWorld.txt?a=b");//File file = new File("文件的路径"); /* * public String getProtocol( ) 获取该URL的协议名 public String getHost( ) 获取该URL的主机名 public String getPort( ) 获取该URL的端口号 public String getPath( ) 获取该URL的文件路径 public String getFile( ) 获取该URL的文件名 public String getRef( ) 获取该URL在文件中的相对位置 public String getQuery( ) 获取该URL的查询名 */// System.out.println(url.getProtocol());// System.out.println(url.getHost());// System.out.println(url.getPort());// System.out.println(url.getFile());// System.out.println(url.getRef());// System.out.println(url.getQuery()); //如何将服务端的资源读取进来:openStream() InputStream is = url.openStream(); byte[] b = new byte[20]; int len; while((len = is.read(b)) != -1){ String str = new String(b,0,len); System.out.print(str); } is.close(); //如果既有数据的输入,又有数据的输出,则考虑使用URLConnection URLConnection urlConn = url.openConnection(); InputStream is1 = urlConn.getInputStream(); FileOutputStream fos = new FileOutputStream(new File("abc.txt")); byte[] b1 = new byte[20]; int len1; while((len1 = is1.read(b1)) != -1){ fos.write(b1, 0, len1); } fos.close(); is1.close(); }}