----------------------
android培训、java培训、期待与您交流! ----------------------
网络编程
网络参考模型:OSI参考模型 TCP/IP参考模型
网络通讯要素:
IP地址:网络中设备的标识,不易记忆,可用主机名;本地回环地址:127.0.0.1,主机名:localhost
端口号:用于标识进程的逻辑地址,不同进程的标识;有效端口:0-65535,其中0-1024被系统使用或是保留端口。
传输协议:即通讯的规则,常见协议有:TCP UDP
TCP和UDP的区别:
UDP(聊天软件,视频会议,桌面共享等常用,如QQ)
1.将数据及源和目的封装成数据包,不需要建立连接
2.每个数据包的大小限制在64k内
3.因无连接,是不可靠协议
4.不需要建立连接,速度快
TCP(下载软件常用,如迅雷)
1.建立连接,形成传输数据的通道
2.在连接中可以进行大数据量传输
3.通过三次握手完成连接,是可靠协议
4.必须建立连接,效率会稍低
UDP传输
Socket
1.Socket就是为网络服务提供的一种机制。
2.通信的两端都有Socket
3.网络通信其实就是Socket间的通信
4.数据在两个Socket间通过IO传输
获取IP地址代码示例:
import java.net.*; class IPDemo { publicstatic void main(String[] args)throws UnknownHostException { //返回本地主机 InetAddress id = InetAddress.getLocalHost(); //获取主机名 Stringname = id.getHostName(); //获取IP地址 Stringaddr = id.getHostAddress(); System.out.println("name:"+name+",address:"+addr); //通过主机名获取IP地址,这种方法很常用 InetAddressi = InetAddress.getByName("www.baidu.com"); Stringname1 = i.getHostName(); Stringaddr1 = i.getHostAddress(); System.out.println("name:"+name1+",address:"+addr1); //一个主机名可能对应多个IP地址,所以用此方法可以遍历出所有IP地址。 InetAddress[]ias = InetAddress.getAllByName("www.baidu.com"); for(InetAddress ia : ias) { System.out.println(ia.getHostAddress()); } } }
网络通讯过程:
1.找到对方IP
2.数据要发送到对方指定的应用程序上,为了标识这些应用程序,所以给这些网络应用程序都用数字进行标识,为了方便称呼这个数字,叫做端口
3.定义通信规则,这个通讯规则称为协议,国际组织定义了通用协议TCP/IP
需求:通过udp传输方式,将一段文字数据发送出去,即定义一个udp发送端。
思路:
1.建立udpsocket服务
2.提供数据,并将数据封装到数据包中
3.通过socket服务的发送功能,将数据包发出去
4.关闭资源
示例代码:
import java.net.*; import java.io.*; class UdpSend { publicstatic void main(String[] args) throws Exception { //1.创建udp服务,通过DatagramSocket对象 DatagramSocketds = new DatagramSocket(8888);//8888为发送端的端口号 //2.确定数据,并封装成数据包 byte[]buf = "hello world".getBytes(); DatagramPacketdp = newDatagramPacket(buf,buf.length,InetAddress.getByName("localhost"),10000); //3.通过socket服务,将已有的数据包发送出去,通过send方法。 ds.send(dp); } //4.关闭资源 ds.close(); } }
需求:定义一个应用程序,用于接收udp协议传输的数据并处理,即定义udp的接收端。
思路:
1.定义udpsocket服务,监听一个端口,其实就是给这个接收网络应用程序定义数据标识。
方便于明确哪些数据过来该应用程序可以处理。
2.定义一个数据包用来存储接收到的字节数据,因为数据包对象中有更多功能可以提取字节数据中的不同数据信息。
3.通过socket服务的receive方法将收到的数据存入已定义好的数据包中。
4.通过数据包对象的特有功能,将这些不同的数据取出,打印在控制台上。
5.关闭资源。
示例代码:
import java.net.*; import java.io.*; class UdpRece { publicstatic void main(String[] args) throws Exception { //1.创建upd socket,建立端点,并监听10000端口 DatagramSocketds = new DatagramSocket(10000); while(true) { //2.定义数据包,用于存储数据 byte[]buf = new byte[1024]; DatagramPacketdp = newDatagramPacket(buf,buf.length); //3.通过服务的receive方法将收到的数据存入到数据包中。 ds.receive(dp); //4.通过数据包的方法获取其中的数据。 Stringaddr = dp.getAddress().getHostAddress(); Stringname = dp.getAddress().getHostName(); Stringdata = new String(dp.getData(),0,dp.getLength()); System.out.println("addr:"+addr+"----name:"+name+"----data:"+data); } //5.关闭资源。 //ds.close(); } }
需求:编写一个聊天程序,有收数据的部分和发数据的部分,这两部分需要同时执行,那就需要用到多线程技术,一个线程控制接收,一个线程控制发送。
因为接收和发送动作是不一致的,所以要定义两个run方法,
而且这两个方法要封装到不同的类中。
示例代码:
import java.io.*; import java.net.*; class Send implements Runnable { privateDatagramSocket ds ; publicSend(DatagramSocket ds) { this.ds= ds; } publicvoid run() { try { BufferedReaderbufr = newBufferedReader(new InputStreamReader(System.in)); Stringline = null; while((line =bufr.readLine())!= null) { if("886".equals(line)) break; byte[]buf = line.getBytes(); DatagramPacketdp=newDatagramPacket(buf,buf.length,InetAddress.getByName("localhost"),10003); ds.send(dp); } } catch(Exception e) { thrownew RuntimeException("发送端失败"); } } } class Rece implements Runnable { privateDatagramSocket ds ; publicRece(DatagramSocket ds) { this.ds= ds; } publicvoid run() { try { while(true) { byte[]buf = new byte[1024*64]; DatagramPacketdp = new DatagramPacket(buf,buf.length); ds.receive(dp); Stringip = dp.getAddress().getHostAddress(); Stringdata = new String(dp.getData(),0,dp.getLength()); System.out.println(ip+":"+data); } } catch(Exception e) { thrownew RuntimeException("接收端失败"); } } } class ChatDemo { publicstatic void main(String[] args) throws Exception { DatagramSocketsendSocket = new DatagramSocket(); DatagramSocketreceSocket = new DatagramSocket(10003); newThread(new Send(sendSocket)).start(); newThread(new Rece(receSocket)).start(); } }
TCP传输
1.Socket和ServerSocket
2.建立客户端和服务器端客户端对应的对象是Socket服务端对应的对象是ServerSocket
3.建立连接后,通过Socket中的IO流进行数据的传输。
4.关闭Socket
需求:创建TCP客户端,通过查阅Socket对象,发现在该对象建立时,就可以去连接指定的主机,因为tcp是面向连接的,所以在建立socket服务时,就要有服务端存在,并连接成功,形成通路后,在该通道进行数据的传输
示例代码:
import java.io.*; import java.net.*; class TcpClient { publicstatic void main(String[] args)throws Exception { //创建客户端的socket服务,指定目的主机和端口 Sockets = new Socket("localhost",10004); //为了发送数据,应该获取Socket流中的输出流 OutputStreamos = s.getOutputStream(); os.write("服务器,我来了".getBytes()); //关闭Socket服务 s.close(); } }
需求:定义TCP服务端,接收数据并打印在控制台上。
示例代码:
import java.io.*; import java.net.*; class TcpServer { publicstatic void main(String[] args)throws Exception { //建立服务端Socket服务,并监听一个端口 ServerSocketss = new ServerSocket(10004); //通过accept方法获取连接过来的客户端对象。 Sockets = ss.accept();//accept是一个阻塞式方法 //获取客户端的IP地址 Stringip = s.getInetAddress().getHostAddress(); System.out.println(ip+".....connected"); //获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据。 InputStreamis = s.getInputStream(); byte[]buf = new byte[1024]; intlen = is.read(buf); Stringdata = new String(buf,0,len); System.out.println(data); s.close();//关闭客户端 ss.close();//关闭服务端,这是一个可选操作。 } }
需求:上传图片
示例代码:
//客户端 import java.io.*; import java.net.*; class UploadPicClient { publicstatic void main(String[] args) throws IOException { //1.创建Socket服务端点 Sockets = new Socket("localhost",50005); //2.读取客户端已有的图片数据 FileInputStreamin = new FileInputStream("c:\\1.png"); //3.通过socket输出流将数据发给服务端 OutputStreamout = s.getOutputStream(); byte[]buf = new byte[1024]; intlen = 0 ; while((len= in.read(buf))!=-1) { out.write(buf,0,len); } //告诉服务器数据写完了。 s.shutdownOutput(); //4.通过Socket输入流读取服务端反馈的信息 InputStreamis = s.getInputStream(); byte[]bufIn = new byte[1024]; intnum = is.read(bufIn); System.out.println(newString(bufIn,0,num)); //5.关闭Socket服务 s.close(); in.close(); } } //服务端 class UploadPicServer { publicstatic void main(String[] args) throws IOException { //1.创建Socket服务,并监听50005端口 ServerSocketss = new ServerSocket(50005); //2.通过accept方法获取连接进来的客户端对象 Sockets = ss.accept(); Stringip = s.getInetAddress().getHostAddress(); System.out.println(ip+".....connected"); //获取客户端发送过来的数据,使用客户端对象的读取流来读取数据。 InputStreamin = s.getInputStream(); //创建一个文件输出流对象,并指定数据存放目的地 FileOutputStreamout = new FileOutputStream("d:\\sever.png"); byte[]buf = new byte[1024]; intlen = 0 ; while((len= in.read(buf))!=-1) { out.write(buf,0,len); } //通过客户端输出流反馈作息给客户端 OutputStreamos = s.getOutputStream(); os.write("上传图片成功!!".getBytes()); //关闭服务 out.close(); s.close(); ss.close(); } }
需求:客户端并发上传图片
示例代码:
//客户端 import java.io.*; import java.net.*; class UploadPicClient { publicstatic void main(String[] args) throws IOException { //主函数传参数 java UploadPicClient c:\1.png //对不符合要求的进行排除 if(args.length!=1) { System.out.println("请选择一个jpg格式的图片文件"); return; } Filefile = new File(args[0]); if(!(file.exists()&&file.isFile())) { System.out.println("上传的文件不存在或者不是文件"); return; } if(!(file.getName().endsWith(".png"))) { System.out.println("上传的文件格式不正确,请重新选择!"); return; } if(file.length()>1024*1024*5) { System.out.println("文件过大,请重新选择!"); return; } Sockets = new Socket("localhost",50005); FileInputStreamin = new FileInputStream(file); OutputStreamout = s.getOutputStream(); byte[]buf = new byte[1024]; intlen = 0 ; while((len= in.read(buf))!=-1) { out.write(buf,0,len); } s.shutdownOutput(); InputStreamis = s.getInputStream(); byte[]bufIn = new byte[1024]; intnum = is.read(bufIn); System.out.println(newString(bufIn,0,num)); s.close(); in.close(); } } /*服务端 为了可以让多个客户端同时并发访问服务端,那么服务端最好就是将每个客户端封装到一个单独的线程中,这样,就可以同时处理多个客户端请求。 如何定义线程呢? 只要明确了每一个客户端要在服务端执行的代码即可,将该代码存入run方法中。 */ class PicThread implements Runnable { privateSocket s ; PicThread(Sockets ) { this.s= s; } publicvoid run() { Stringip = s.getInetAddress().getHostAddress(); intnum = 1; try { System.out.println(ip+".....connected"); InputStreamin = s.getInputStream(); Filefile = new File("d:\\server.png"); while(file.exists()) file= new File("d:\\server("+(num++)+").png"); FileOutputStreamout = new FileOutputStream(file); byte[]buf = new byte[1024]; intlen = 0 ; while((len= in.read(buf))!=-1) { out.write(buf,0,len); } OutputStreamos = s.getOutputStream(); os.write("上传图片成功!!".getBytes()); out.close(); s.close(); } catch(Exception e) { thrownew RuntimeException(ip+"上传失败^_^"); } } } class UploadPicServer { publicstatic void main(String[] args) throws IOException { ServerSocketss = new ServerSocket(50005); while(true) { Sockets = ss.accept(); newThread(new PicThread(s)).start(); } } }
需求:模拟一个简单的浏览器
示例代码:
import java.io.*; import java.net.*; class MyIE { publicstatic void main(String[] args)throw Exception { Sockets = new Socket("127.0.0.1",14000); PrintWriterout = new PrintWriter(s.getOutStream(),true); out.println("GETHTTP/1.1"); out.println("Accept:*/*"); out.println("Accept-Language:zh-cn"); out.println("Host:127.0.0.1:14000"); out.println("Connection:Keep-Alive"); out.println();//一定要打这个空格。 BufferedReaderbufr = newBufferedReader(new InputStreamReader(s.getInputStream())); Stringline = null; while((line= bufr.readLine())!=null) { System.out.println(line); } s.close(); } }
需求:自定义一个服务器
示例代码:
import java.io.*; import java.net.*; class ServerDemo { publicstatic void main(String[] args) throws Exception { ServerSocketss = new ServerSocket(14000); while(true) { Sockets = ss.accept(); newThread(new ServerThread(s)).start(); } } } class ServerThread implements Runnable { privateSocket s ; ServerThread(Sockets) { this.s= s; } publicvoid run() { System.out.println(s.getInetAddress().getHostAddress()); try { InputStreamin = s.getInputStream(); byte[]buf = new byte[1024]; intlen = 0; while((len= in.read(buf))!=-1) { System.out.println(newString(buf,0,len)); } PrintWriterout = new PrintWriter(s.getOutputStream(),true); out.println("<b>客户端你好"); s.close(); } catch(Exception e) { thrownew RuntimeException("failed"); } } }
URL
类URL
代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。
常用方法:
getContent() |
|
getContent(Class[] classes) |
|
int |
getDefaultPort() |
getFile() |
|
getHost() |
|
getPath() |
|
int |
getPort() |
getProtocol() |
|
getQuery() |
URLCollection
它代表应用程序和 URL 之间的通信链接。此类的实例可用于读取和写入此 URL 引用的资源。通常,创建一个到 URL 的连接需要几个步骤:
openConnection() |
connect() |
对影响到远程资源连接的参数进行操作。 |
与资源交互;查询头字段和内容。 |
---------------------------->
时间
- 通过在 URL 上调用 openConnection 方法创建连接对象。
- 处理设置参数和一般请求属性。
- 使用 connect 方法建立到远程对象的实际连接。
- 远程对象变为可用。远程对象的头字段和内容变为可访问。
使用以下方法修改设置参数:
- setAllowUserInteraction
- setDoInput
- setDoOutput
- setIfModifiedSince
- setUseCaches
使用以下方法修改一般请求属性:
- setRequestProperty
在建立到远程对象的连接后,以下方法用于访问头字段和内容:
- getContent
- getHeaderField
- getInputStream
- getOutputStream
某些头字段需要经常访问。以下方法:
- getContentEncoding
- getContentLength
- getContentType
- getDate
- getExpiration
- getLastModifed
----------------------
android培训、java培训、期待与您交流! ----------------------