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


网络编程

概述:

通讯三要素:

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();//当客户端关闭,这里就会返回-1
				if("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地址,最后才访问网站



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值