黑马程序员—java基础复习—网络编程

本文详细介绍了网络通信的基础知识,包括OSI参考模型、网络通讯要素、Socket套接字、UDP与TCP协议的区别与应用,以及如何使用Java进行网络编程。重点阐述了Socket的建立、数据的发送与接收过程,提供了实际的代码示例。


------- android培训java培训、期待与您交流! ----------

1、网络参考模型

                        OSI参考模型                                                          TCP/IP参考模型

                            应用层                                          

                            表示层                                                                        应用层

                            会话层

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

                            传输层                                                                        传输层

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

                            网络层                                                                         网际层

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

                        数据链路层

                            物理层                                                                          主机值网络层

2、网络通讯要素

         ①IP地址InetAddress

             IP地址是设备在网络中的标示,IP地址的长度为32位(共有2^32个IP地址),分为4段,每段8位,用十进制数字表示,每段数字范围为0~255,段与段之间用句点隔开。一般不容易记忆,可使用主机名。例如本地回环地址:127.0.0.1其主机名为:localhost。

         ②端口号Port

             用于标识进程的逻辑地址,不同进程的标识,有效端口:0~65535,其中0~1024系统使用或保留端口。

         ③传输协议

              即网络间的通讯规则,常用的有TCP/IP协议、UDP

              TCP:

                        即传输控制协议,在通讯时通过三次握手完成建立连接,形成传输数据的通道,在连接中会进行大量的数据传输,效率会稍低。当传输出现错误时能自动予以纠正。类似于打电话,需接通后才能对话。

              UDP:

                         即用户数据包协议,在数据进行传输时不需要建立连接,是一种不可靠的协议,其将数据及原和目的地封装成大小限制在64K的数据包中,进行传输,当传输出现错误时会将丢弃。类似于对讲机,按下对讲机不管是否有人接通都可以进行说话。

3、Socket套接字

          网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。网络的通信其实就是数据在Socket间通过IO进行的通信

4、UDP用户数据包协议         

         使用UDP进行通讯,发送端的实现:

          在发送端,要在数据包对象中明确目的地 IP及端口

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class SendMessage {
	public static void main(String[] args) {
		try {
			//建立发送端口,指定端口为10000
			DatagramSocket ds=new DatagramSocket();
			//建立数据,并封装成数据包DatagramPacket(数据,数据长度,目的地址,端口)
			byte[] buf="hahahah".getBytes();
			DatagramPacket dp=new DatagramPacket(buf, buf.length,InetAddress.getByName("192.168.1.101"), 10000);
			//发送数据报
			ds.send(dp);
			//关闭资源
			ds.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
       接受端的实现:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class ReceiveMessage {
	public static void main(String[] args) {
		//建立udp socket 
         try {
			DatagramSocket ds=new DatagramSocket(10000);
		//定义一个用于接收数据的数据包	
			byte[] buf=new byte[1024];
			DatagramPacket dp=new DatagramPacket(buf, buf.length);
			//接收数据
			ds.receive(dp);
			//通过数据包的方法获取其中的数据。
			String data=new String(dp.getData(),0,dp.getLength());
			//获取ip地址
			String ip=dp.getAddress().getHostAddress();
			System.out.println(ip+":"+data);		
		} catch (Exception e) {
			e.printStackTrace();
		}      
	}
}
5、TCP协议

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

           客户端的实现:

            1、创建Socket服务。并指定要连接的主机和端口。
            2、创建客户端的socket服务。指定目的主机和端口
            3、为了发送数据,应该获取socket流中的输出流。

             

public class SendMessage {
	public static void main(String[] args) {
		try {
			//创建Socket服务,指定要连接的主机和端口
			Socket s=new Socket(InetAddress.getByName("192.168.1.101"),10000);
			//从键盘获取数据
			BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
			//将数据通过socket通过输出流写出
			BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
			//PrintWriter pw=new PrintWriter(s.getOutputStream(),true);
			String line;
			while((line=br.readLine())!=null){
				if("over".equals(line))
					break;
				//pw.println(line);
				bw.write(line);
				bw.newLine();//readLine将换行符最为结束标记,并不将换行符写入,需手动添加
				bw.flush();//刷新
			}
			//关闭资源
			s.close();
			//pw.close();
			bw.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

          服务端的实现:

                 1,建立服务端的socket服务。ServerSocket();
                         并监听一个端口。
                 2,获取连接过来的客户端对象。
                         通过ServerSokcet的 accept方法。没有连接就会等,所以这个方法阻塞式的。
                3,客户端如果发过来数据,那么服务端要使用对应的客户端对象,并获取到该客户端对象的读取流来读取发过来的数据。并打印在控制台。
                4,关闭服务端。(可选)

class ReceiveMge{
	public static void main(String[] args){
		try {
			//建立服务端,并监听端口10000
			ServerSocket ss=new ServerSocket(10000);
			//获取连接过来的套接字
			Socket s=ss.accept();
			//
			BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream()));
			BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));
			PrintWriter pw=new PrintWriter(System.out,true);
			String line;
			while((line=br.readLine())!=null){
				bw.write(line.toUpperCase());
				bw.newLine();
				bw.flush();
				pw.println(line.toUpperCase());
			}
			br.close();
			bw.close();
			//pw.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

总结:

        1、reader是阻塞式方法,readLine()需要读取到换行符,才会返回,当客户端将输入通过write方法写给服务器时,如果使用缓冲流,必须刷新,并且加上换行符,因为,当从键盘录入时,输入的换行符,在使用readLine()读入到内存中时,就被客户端的readLine()作为结束符使用了,读入到内存中的字符串是没有换行符的,在服务端读取后,将字符串处理后,发送回客户端是,也需要加上换行符并刷新。
        2、PrintWrite(File/String/writer/out, boolean)自带刷新功能,PrintWriter.println();自动结束本行。
        3、在一般使用中,自定义结束标记较麻烦,一般在写完数据时使用s.shutdownOutput(),告诉服务端数据写完了。
6、URL对路劲实现封装
          通过将路径封装到URL中,URL内部实际对Socket进行了封装,是从应用层实现对资源的访问,通过ISO模型可知,能够将获取的资源的HTTP请求头去掉。Socket是发生在链路层,URL.openConnection()是发生在应用层。

          常用的方法:

               ① getFile()获取URL的文件名

               ②getPath()获取此URL的路径

                    getPath()和getFile()的区别:当url后面带有访问参数时,getFile()会包括访问参数。

               ③getHost()获取URL的主机名

               ④getPort()获取URL端口号,getPort(),当没指定端口是返回值为-1。使用默认端口80。              

               ⑤getQuery()获取URL的查询部分

                      getQuery()当url后面跟有访问参数时,能够获取访问参数,没有为null。

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class demo {
	public static void main(String[] args){
		try {
			URL url=new URL("http://192.168.1.101:8080/mail/1.html?a=1&b=2");
			String path=url.getPath();
			String file=url.getFile();
			int port=url.getPort();
			String query=url.getQuery();
			String host=url.getHost();
			//获取连接
			HttpURLConnection conn=(HttpURLConnection) url.openConnection();
			InputStream in=conn.getInputStream();//获取流对象
			byte[] buf=new byte[1024];
			int len=in.read(buf);
			System.out.println(new String(buf,0,len));
			System.out.println("path:"+path+",\r\n"+"file:"+file+",\r\n"+"port:"+port+",\r\n"+"query:"+query+",\r\n"+"host:"+host);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值