网路编程(概述、InetAddress、Socket服务、URL)

来源:互联网 发布:硬盘坏了数据恢复 编辑:程序博客网 时间:2024/06/02 09:45


网络编程

概述:

通讯三要素:

1、IP地址:找到对方,通过IP地址

2、逻辑端口:数据要发送到对方指定的应用程序上,为了标识这些应用程式,所以给这些网络应用程序都用数字进行标识。这个标识就叫做端口。

3、协议:定义通讯规则。这个通讯规则成为协议。

国际组织定义了通用协议:TCP/IP

端口范围:0~~65535,0~1024被系统保留

常见端口:web:80   ; Tomcat:8080   ;  MySQL:3306

常见协议:TCP 、UDP


本地主机IP地址:127.0.0.1,名称:localhost。两者对应,跟网址和域名的关系。

————————————————————————————

InetAddress:用于描述IP的类

方法:

String  getHostAddress();:返回对象IP地址的字符串形式

String  getHostName(); :返回对象的主机名

static   InetAddress  getLocalHost():获取本地主机对象

static   InetAddress  getByName("IP地址"):获取IP地址或者域名获取主机对象。

static  InetAddress[]  getAllByAddress("域名"):通过主机名或者域名获取不同IP地址的主机对象数组。

注:如果IP地址和对应的主机名这个映射关系没有在网络上,其他主机通过IP地址去搜索到了,但是会有没解释成功的情况,getHostName()获取的还是IP的地址;getHostName();会有一个解释过程。

       当输入域名用getByName方法获取主机对象时,IP地址并不是唯一的。因为网络上的服务器可能有多台,对应不用的IP地址,这时就要用:getAllByAddress方法。大部分用getAllByAddress方法为主,因为getHostName方法需要解释。

public static void main(String[] args) throws Exception{InetAddress i = InetAddress.getLocalHost();System.out.println("address"+i.getHostAddress());System.out.println("name:"+i.getHostName());InetAddress ia = InetAddress.getByName("www.163.com");System.out.println("address:"+ia.getHostAddress());System.out.println("name:"+ia.getHostName());InetAddress[] ias = InetAddress.getAllByName("www.baidu.com");System.out.println("Address:"+ias[0].getHostAddress());System.out.println("Name:"+ias[0].getHostName());System.out.println("Address:"+ias[1].getHostAddress());System.out.println("Name:"+ias[1].getHostName());}
——————————————————

Socket

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

通信两端都有Socket,网络通讯其实就是Socket间的通讯,通过IO传输

IP地址最后一段255是广播地址,会发送到当前网段的所有机器上(1-254)


UDP传输:
特点:

1、面向无连接;

2、发送时需要把数据封装成一个个数据报,每个数据包不能超过64K;

3、速度快,容易丢失数据报;

4、因为特点1,所以是不可靠的协议;

面向无连接:网络通讯有接收端和发送端,发送端发送数据包到接收端,接收端在不在网络上都没关系,在就接收到,不在数据包就丢失。

应用:聊天工具如:qq、icq之类的就是UDP,视频通讯之类的也是UDP

UDP对象:DatagramSocket 用于发送和接收

UDP传输数据包对象:DatagramPacket;用于接收和封装数据。凡是构造函数参数要IP地址对象和端口的都是用于构造发送数据包。空参数是用于接收数据。

UDP发送端思路:通过UDP传输方式,将一段数据发送出去。

1、建立UDPSocket服务(DatagramSocket对象)

2、提供数据,并将数据封装到数据包中(DatagramPacket对象)

3、通过Socket服务的发送功能,将数据包发送出去。(ds.send(dp))

{DatagramSocket ds = new DatagramSocket();BufferedReader br = new BufferedReader(new InputStreamReader(System.in));String len = null;do{len =br.readLine();byte[] but =len.getBytes();DatagramPacket dp = new DatagramPacket(but,but.length,InetAddress.getByName("192.168.2.255"),11111);ds.send(dp);}while(!len.equals("over"));ds.close();br.close();}

UDP发送端思路:定义一个应用程序,用于接收UDP协议传输的数据并处理

1、定义UDPSocket服务,通常会监听一个端口,其实就是给这个接收网络应用程序定义数字标识。方便于明确哪些数据传输过来后是该应用程序可以处理的。

2、定义一个空的数据包,用于存储接收到的字节数据。因为数据包对象中有更多的功能可以崎岖字节数据中的同数据信息。

3通过Socket服务的receive方法接收到的数据存入已定义好的数据包中。

4、通过数据包对象的特有功能,将这些不同的数据取出。

5、关闭资源。

注意:不手动定义端口的话,虚拟机会自动添加一个端口,但是就会和发送端定义的端口对应不上,就接收不到数据。另外,DatagramPacket中的getPort()是获取发送端的自身的端口,而不是发送端的目的端口。

public static void main(String[] args)  throws Exception{DatagramSocket ds = new DatagramSocket(11111);byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf,buf.length);String str = null;while(true){ds.receive(dp);str = new String(buf,0,dp.getLength());String ip = dp.getAddress().getHostAddress();System.out.println(ip+"::"+str);}}

TCP传输:

特点:

1、面向连接,用3次握手判断

2、没有数据包大小限制

3、速度相对稍慢。

4、是可靠的协议。

三次握手:就是发送端发送数据到接收端,接收端收到后反馈数据给发送端通知接收到。发送端接收到反馈数据后,再反馈数据给接收端通知收到了。

TCP对象:Socket客户端和ServerSocket服务端

客户端在建立对象时,就去连接指定主机。因为TCP是面向连接的,所以在Socket服务建立时,就要有服务端存在,才能连接成功。形成通道后,在该通路进行数据的传输。

建立对象后是通过Socket流通讯:

OutputStream  getOutputStream():输出流,从调用对象往外流。

InputStream  getInputStream():输入流,接收外面往调用对象。

客户端:

public static void main(String[] args) throws IOException{//创建客户端的socket服务。指定目的主机和端口Socket sock = new Socket("192.168.2.100",11011);//为了发送数据,应该获取socket流中的输出流。OutputStream os = sock.getOutputStream();//发送数据os.write("dfsgdfgsdfgsdfgsdfgsd".getBytes());sock.close();}


服务端通过获取客户端的Socket对象的影像,来进行不同客户端的管理。

Socket  accept():获取连接到服务端的客户端的Socket对象。

服务端:

1、建立服务端的Socket服务:ServerSocket(),并监听一个端口。

2、获取连接过来的客户端对象。通过ServerSocket的accept方法;没有连接请求就会等待,左移这个方法是阻塞式。

3、客户端如果发送数据过来,那么服务端要使用对应的客户端对象,并获取到该对象的读取流来读取发送过来的数据。

4、关闭服务端(可选,因为服务端的存在并不为了单一客户端。所以服务端一般长期开着,灯虎客户端的接入。所以这里可以通过关闭服务端上的客户端对象来完成断开连接。)

public static void main(String[] args) throws IOException{//建立服务端socket服务。并监听一个端口。ServerSocket ss = new ServerSocket(11011);while(true){//通过accept方法获取连接过来的客户端对象。Socket sock = ss.accept();//获取客户端发送过来的数据,那么要使用客户端对象的读取流来读取数据。InputStream is = sock.getInputStream();String ip = sock.getInetAddress().getHostAddress();byte[] buf = new byte[1024];int len = is.read(buf);System.out.println(ip+"::"+new String(buf,0,len));//服务端关闭客户度的连接sock.close();}}


注意:当客户端和服务端交流,都用Buffered装饰和转换流进行键盘的读取和反馈时,服务端用readLine方法读取客户端发送数据,客户端在发送数据时,除了要write()以外还要花上newLine()作为结束标记,不然服务端的readLine()会一直等待,同理,客户端读取服务端readLine()方法也是一样。还有write()和newLine()后要记得flush()刷新。

/*演示tcp的传输的客户端和服务端的互访。需求:客户端给服务端发送数据,服务端收到后,给客户端反馈信息。*//*客户端:1,建立socket服务。指定要连接主机和端口。2,获取socket流中的输出流。将数据写到该流中。通过网络发送给服务端。3,获取socket流中的输入流,将服务端反馈的数据获取到,并打印。4,关闭客户端资源。*/import java.io.*;import java.net.*;class myServer2{public static void main(String[] args)  throws Exception{//建立服务端ServerSocket server = new ServerSocket(10022);while(true){//获取客户端对象Socket s = server.accept();String ip = s.getInetAddress().getHostAddress(); System.out.println(ip+"...连接服务器!");//客户端对象输出流和读取流//BufferedWriter bfos = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));BufferedReader bfis = new BufferedReader(new InputStreamReader(s.getInputStream()));//简化代码不用BufferedWriter和转换流,用PrintWriter;PrintWriter pw = new PrintWriter(s.getOutputStream(),true);//循环获取客户端信息和进行反馈while(true){String line = bfis.readLine();//当客户端关闭,这里就会返回-1if("over".equals(line))break;System.out.println(ip+"::"+line);pw.println(line.toUpperCase());/*bfos.write(line.toUpperCase());//跟客户端一样,要加上,不然客户端那里也是等待bfos.newLine();bfos.flush();*/}System.out.println(ip+"...以结束连接!");s.close();}}}class  myTcpDemo2{public static void main(String[] args) throws Exception{//客户端连接Socket sock = new Socket("192.168.2.100",10022);//获取键盘录入BufferedReader bfr = new BufferedReader(new InputStreamReader(System.in));//客户端输出流和读取流//BufferedWriter bfos = new BufferedWriter(new OutputStreamWriter(sock.getOutputStream()));BufferedReader bfis = new BufferedReader(new InputStreamReader(sock.getInputStream()));//简化代码不用BufferedWriter和转换流,用PrintWriter;PrintWriter pw = new PrintWriter(sock.getOutputStream(),true);String line = null;while((line=bfr.readLine())!=null){if("over".equals(line)){pw.println(line);/*bfos.write(line);bfos.flush();*/break;}pw.println(line);/*bfos.write(line);//这里要加上newLine方法,不然服务端那里的readLine方法没有读取到换行,就会一直等待bfos.newLine();bfos.flush();*/String str = bfis.readLine();System.out.println("Server::"+str);}bfr.close();sock.close();}}

————————————————————————————————

URL

URL代表同意资源定位符,URI也是,不过比URL的范围大。

构造函数:以String形式传入整个网址,或者也可以根据不同的部分分别传入协议、域名、端口、文件等

常见方法

String  geProtocol():获取协议,如http、ftp

String  getHost():获取主机的IP地址或者域名

int  getPort():获取端口,未设置返回默认-1,即80端口

String  getPath():获取路径,但网址不带参数时两者一样,网址带上参数后,getFile就跟上参数,getPath就不跟

String  getFile():获取文件,但网址不带参数时两者一样,网址带上参数后,getFile就跟上参数,getPath就不跟

String getQuery():获取路径后面的参数,没有时返回null

URLConnection  openConnection():获取URL的连接对象URLConnection,一调用该方法就已经连接上了服务端,请求头也已经发送,之后只要获取读取流读取服务端发送过来的数据即可。

InputStream  openStream():就是openConnection().getInputStream()的缩写,先连接,再获取读取流

public static void main(String[] args) throws Exception{URL url = new URL("http://192.168.2.100:8080/myweb/demo.html");URLConnection conn = url.openConnection();System.out.println(conn);InputStream in = conn.getInputStream();byte[] buf = new byte[1024];int len = in.read(buf);System.out.println(new String(buf,0,len));}

DNS服务器就是域名解释服务器,记录了域名和IP地址的映射关系

IE访问网络:先去本机的HOSTS文件查找网址的IP地址;没有时再到DNS服务器上查找网址的IP地址,最后才访问网站