黑马学习日记_网络编程篇 java网络编程
程序员文章站
2024-02-01 13:22:58
...
1、IP、端口号和传输协议?
IP:在网络中双方进行通讯,必须要知道对方的IP地址,就类似于我们的身份证是唯一的,而IP地址就是这台电脑在网络中的地址,只有知道地址才能进行通讯。我们现在用的IP地址是IPv4它分为四段 每一段的取值范围是0~255,127.0.0.1是本机默认IP也就是常说的本地回环地址,随着网络用户的不断增加IPv4已快不能满足人们的需求,就产生了IPv6它是有字母和数字组合,排列组合更多,可以解决网络地址不足。
端口号:用于标示进程的逻辑地址不同进程的标示,一个网络应用程序会对应一个或多个数字标示(端口号),例如当两台电脑进行通讯,A通过QQ应用程序发送了一段消息给B,但是B电脑上有很多应用程序,这段消息靠谁来解析呢?为了解决这个问题,我们为应用程序定义一个数字标示即端口号,用于接收和处理发到该端口号上的数据。端口号范围是0~65535其中0~1024被系统程序所占用。常见的端口号:WEB端口80、Tomact服务器端口号8080、mysql端口是3306等。
传输协议:就是通讯规则,两台电脑进行通讯,要符合一定的协议,只有这样才能正常交流。好比两个人交流一样,只有我们所说的语言一样,交流才不会有问题,如果你说日语,我说汉语你听不懂我也听不懂。常见的协议有TCP和UDP两种协议,通用协议是TCP/IP。
2、网络模型
OSI参考模型:OSI(Open System Interconnect)开放式系统互联。 一般都叫OSI参考模型,是ISO(国际
标准化组织)组织在1985年研究的网络互联模型。
TCP/IP参考模型:简化成了四层,应用层表示层会话层为化为应用层,传输层仍为传输层,网络测光为网
际层,数据链路层与物理层合为主机至网络层。
IP地址协议在网际层上,TCP、UDP协议在传输层上,我们搞软件开发,就在网络层与传输层上混。
3、Java中描述IP地址的类 InetAddress
java.net包中InetAddress是描述IP的它为我们提供了许多方法操作IP。
InetAddress.getLocaHost()返回InetAddress对象,是一个静态的方法并且有异常抛出使用时注意。
String getHostName() 获取本机名称,主要用该方法。
InetAddress.getByName(String 任意主机名称)。如果IP地址和本机名称没有注册关系则返回地址eg:www.baidu.com为主机名称但它可以对应多个IP地址(映射),所以通过getByName()方法返回的InetAddress对象不是一个,所以有一个方法是返回了一个InetAddress[ ]的数组即static InetAddress [ ] getAllByName(String host).
4、UDP协议和TCP协议
UDP特点:
1、面向无连接,有两段你发我我发你,把数据发出去,不管你在不在,在就接受数据包,不在数据包丢掉(邮局寄东西)
2、将数据及源和目的封装成数据包,不需要建立连接
3、每个数据包的大小限制在64K内
4、因无需连接是不可靠协议
5、不需要建立连接速度快
总结:不可靠协议但速度快容易丢包
TCP特点:
1、必须面向连接,要想通讯对方必须在,先确定对方在不在,在就进行数据传输。怎么判断对方在不在?通过三次握手判断通路是否连接。
2、建立连接形成传输数据通路
3、在连接中进行大数据量传输
4、通过三次握手完成连接是可靠协议
5、必须建立连接效率低
5、Socket
Socket就是为网络服务提供的一种机制,通讯的两端都有Socket,网络通讯其实就是Socket间的通讯数据在两个Socket间通过IO传输。就好比港口,只有双方都有港口才能把东西运过去。
6、UDP的Socket服务建立步骤?
DatagramSocket此类标示用来发送和接受数据包的套接字(插座)
方法:send(DatagramPacket p)发送
receive(DatagramPacket p)接受
数据已包的形式发送和接受,所以Java为我们提供了DatagramPacket对象,因为数据包中有许多对象:属性 IP 协议
步骤:1、建立UDPSocket服务(相当于邮局)
2、提供数据并将数据封装到数据包中(要邮寄的东西例如 衣服)
3、通过Socket服务的发送功能将数据发送出去
发送端
// 创建UdpSocket服务通过DatagramSocket对象
DatagramSocket ds = new DatagramSocket( );
//确定要发送的数据,并将数据封装成包——通过DatagramPacket数据包对象,因为该对象一初始化就要有指定的数据、数据的大小、IP地址、端口号DatagramPacket(byte[] buf,int length,InetAddress,int port)
byte [ ] buf = "udp wo lai la".getBytes();//要发送的数据
//将数据封装成包
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.0.1"),10000);
//通过DatagramSocket对象的发送功能将数据发送出去
ds.send(dp);
//关闭资源
ds.close();
具体代码如下:
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.Inet4Address; import javax.sound.sampled.Line; public class SocketOne { public static void main(String[] args)throws Exception { //1,创建Udp服务,通过DatagramSocket对象。 DatagramSocket dSocket=new DatagramSocket(); //2,创建数据封装成数据包。DatagtamPacket(byte[] buf,int length,InetAdress address,int port ) BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(System.in)); String line=null; while((line=bufferedReader.readLine())!=null) { if(line.equals("stop")) break; byte [] buf=line.getBytes(); DatagramPacket dPacket=new DatagramPacket(buf, buf.length,Inet4Address.getByName("127.0.0.1"),49991); //3,通过Udp的send方法发送出去把数据包 dSocket.send(dPacket); //4,关闭资 } dSocket.close(); } }
接收端
步骤:
1、定义UdpSocket服务通常会监听一个端口方便于明确哪些数据过来,其实就是给这个网络应用程序定义一个标示
2、定义一个数据包(没有数据)因为要存储接收到的字节数据,因为数据包对象中有更多功能可以提取字节数据中的不同数据信息
3、通过Socket服务的receive方法将接收到的数据存入到以定义好的数据包中
4、通过数据包对象的特有功能将这些不同的数据取出打印在控制台上
5、关闭资源
相关代码:
1、创建UdpSocket服务建立断点,构造函数中可以定义端口
DatagramSocket ds = new DatagramSocket(10000);
2、定义数据包用于存储接收到的数据
byte [ ] buf = new byte[1024];
Datagrampacket dp = new Datagrampacket(buf,buf.length);//数据包的大小
3、通过服务的接受方法receive阻塞式方法( Datagrampacket dp)将接受到的数据存入到数据包中
ds.receive(dp);
4、通过数据包总的方法获取其中的数据(地址,端口,数据)
String ip = dp.getAddress().getHostName() ;//获取Ip地址
String data = new String(dp.getData(),0,dp.getLength());//获取数据
int port =dp.getPort( );//获取端口
System.out.println(ipa+"::"+data+"::"+port);
5、关闭资源
ds.close( );
接收端代码实现:
import java.io.BufferedWriter; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.sql.Date; public class UdpRecOne { public static void main(String[] args) throws Exception { //1,创建一个接收端,并监听一个端口 DatagramSocket dSocket=new DatagramSocket(49991); BufferedWriter bufferedWriter=null; //2,定义缓冲区数组和数据包用于接收发送端数据 while(true){ byte[] buf=new byte[1024]; DatagramPacket dPacket =new DatagramPacket(buf, buf.length); //3,socket的接收方法 dSocket.receive(dPacket); //4,dataPacket的获取目标主机地址,端口的号码,还有数据(getData()) String ipString=dPacket.getAddress().getHostAddress(); String dataString=new String(dPacket.getData(),0,dPacket.getLength()); int port =dPacket.getPort(); //5,为了证明是否收到了数据,定义一个IO流,将收到的数据存入磁盘 bufferedWriter=new BufferedWriter(new OutputStreamWriter(new FileOutputStream("d:\\terew.txt",true))); bufferedWriter.write(dataString+" "+ipString+" "+port); bufferedWriter.newLine(); //bufferedWriter.flush(); // dSocket.close(); bufferedWriter.close(); // System.out.println(ipString); System.out.println(ipString+"::"+dataString); } } }
UDP键盘录入方式数据:
就是把数据存放到数据包里的时候,数据的源变了,不再是内存上的数据而是键盘录入的了,这时候就
想到了io流时总结的规律了,也就是那几个明确,明确源和目的;明确是否为纯文本;明确设备;
部分代码:
DatagramSocket ds =new DatagramSocket(); //2.把数据封装成包 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); String line = null; while((line=bufr.readLine())!=null) { if("886".equals(line)) break; byte[] data = line.getBytes(); DatagramPacket dp = new DatagramPacket(data,data.length,InetAddress.getByName("192.168.126.1"),10000); ds.send(dp); }
7、TCP传输的建立
通过查阅Socket对象,发现在该对象建立时就要去连接指定主机,因为TCP是面向连接的,所以在建立Socket服务时就要有服务端存在,并连接成功后,在该通道进行数据传输。
客户端步骤:
1、创建Socket服务并指定要连接的主机和端口
Socket(InetAddress address,int port)或Socket(String host,int port)
Socket s = new Socket("192.168.0.1",10001);//该语句一建立成功就会形成一个通路,该通路内有自己的传输数据方式就是有自己的流,获取通路中流的方法getOutputStream(), getInputStream()通路一建立就有流
2、为了发送数据 应该获取Socket流中的输出流
OutputStream os = s.getOutputStream( );
out.write("TCP ge men lai la ');
3、关闭资源
s.close( ) ;
服务端ServerSocket步骤:
1、建立服务端的Socket服务 通过ServerSocket并监听一个端口
ServerSocket ss = new ServerSocket(10001);
2、获取连接过来的客户端对象,通过ServerSocket的accpet()方法阻塞式,没有连接就会等
Socket s = ss.accpet();//返回Socket对象
3、客户端如果发过来数据,那么服务端要使用对应得的客户端对象,并获取到该客户对象的读取流,来读取发过来的数据并打印到控制台
InputStream is = s .getInputStream();这个源是网络流
4、关闭服务端(可选操作)
8、TCP练习
TCP传输练习
需求:建立一个文本转换服务器。
客户端给服务端发送文本,服务单会将文本转成大写在返回给客户端。
而且客户度可以不断的进行文本转换。当客户端输入over时,转换结束。
分析:
客户端:
既然是操作设备上的数据,那么就可以使用io技术,并按照io的操作规律来思考。
源:键盘录入。
目的:网络设备,网络输出流。
而且操作的是文本数据。可以选择字符流。
都是文本数据,可以使用字符流进行操作,同时提高效率,加入缓冲。
思路:
1,建立服务。
2,获取键盘录入。
3,将数据发给服务端。
4,获取服务端返回的大写数据。
5,结束,关资源。
-----------------------------------------------------------------------
但是按上面写的话,只能一次传一个,就是服务器一次只能接受一个客户端对象,这显然是不行的,像
百度新浪不可能是对一个人服务完之后再去服务下一个的,那怎么解决呢,这就用到了多线程,让每一
个客户端连接成功之后都去创建一个线程,然后你该干嘛干嘛,就是来一个人创建一个线程来一个人创
建一个线程,这样是不是就可以并发上传图片啦?
那具体代码怎么写呢?我们可以把每个线程都需要执行的部分放到线程的run方法中,然后让实现Runnable
接口的类的构造函数都接受一个客户端Socket对象,然后在服务端的主线程上写一个while(true)循环,让
它循环的接收Socket对象并传给线程累的构造函数。
部分代码:
ServerSocket ss = new ServerSocket(10086); while(true) { Socket s = ss.accept(); PicThread pt = new PicThread(s); Thread t = new Thread(pt); t.start(); }---------------------------------------------------------------------------------------------------------------------------
自定义浏览器: 在文本框中输入网址点击转到弹出相应网址,用到了图形化界面。 部分代码: private void showDir()throws Exception { String url = tf.getText();//http://192.168.1.254:8080/myweb/demo.html //浏览器是客户端,要想与服务前连接必然要创建Socket并把主机与端口传进来 //输入一个网址的话,要获得主机与端口,那就需要从字符串中截取了 int index1 = url.indexOf("//")+2; int index2 = url.indexOf("/",index1); //取"//"与第一个"/"之间表示主机ip与端口的那个子串 String str = url.substring(index1,index2); //在“ :”出切割成一个字符数组, String[] arr = str.split(":"); //第一个是ip第二个是端口 String host = arr[0]; int port = Integer.parseInt(arr[1]); //然后创建Socket进行数据操作 Socket s = new Socket(host,port); PrintWriter out = new PrintWriter(s.getOutputStream(),true); //向服务器发送一些消息头 out.println("GET /myweb/demo.html HTTP/1.1"); out.println("Accept: */*"); out.println("Accept-Language: zh-cn"); out.println("Host: 192.168.1.254:11000"); out.println("Connection: closed"); //消息头与请求体之间一定要用空格隔开 out.println(); out.println(); BufferedReader bufr = new BufferedReader(new InputStreamReader(s.getInputStream())); String line = null; while((line=bufr.readLine())!=null) { //将从服务器读取的数据添加到文本区域中 ta.append(line+"\r\n"); } s.close(); }
------------------------------
9、URL类--URLConnection 从上面知道我们输一个url路径,然后想那个服务器发送请求,要先把那个url路径中的主机和端口获取 到然后再创建Socket服务才能与服务器连接,这期间又是获取子串又是切割冒号,是不是很麻烦啊?在 java中万物皆对象,这么麻烦在java中他肯定会封装一个对象来便于我们这样的操作,查看API发现URL 类正是这样的,它把这一系列麻烦的操作都封装起来了,我们只要拿过来调用就行了。 其中的方法有: String getFile(): 获取此 URL 的文件名。 String getHost(): 获取此 URL 的主机名(如果适用)。 String getPath(): 获取此 URL 的路径部分。 int getPort(): 获取此 URL 的端口号。 String getProtocol(): 获取此 URL 的协议名称。 String getQuery(): 获取此 URL 的查询部 这样是不是就方便了许多啊?这还不算URL类中还有一个openConnection()方法,它可以直接给你连接好 服务器然后给你返回来个连接对象URLConnection。然后你可以用URLConnection的方法获取Socket流然 后直接操作数据。更爽的是它还有一个openStream方法可以直接返回一个用于从该连接读入的InputStream 输入流,是不是很爽,你都不用再创建Socket然后再用Socket对象获取流了。 部分代码: URL url = new URL("http://192.168.1.254:8080/myweb/demo.html"); //用URL中的openConnection()方法直接创建连接 URLConnection conn = url.openConnection(); //URLConnection是一个抽象类,它有两个子类 System.out.println(conn); //openStream方法其实就是这样:openConnection().getInputStream() InputStream in = conn.getInputStream(); byte[] buf = new byte[1024]; int len = in.read(buf); System.out.println(new String(buf,0,len));
---------------------------------------------------------------
10、域名解析
浏览器中输入一个网址访问某台主机的时候,它到底做了什么事情?**** 例如:http://192.168.126.1:8080/myweb/demo.html 首先浏览器在解析完这句话以后他是不是要先看协议(如http://)啊,看完之后会启动相应的协议并解析后面的主机和端口,并把它们封装成Socket。但是我们在输入的时候往往不写主机地址,而是写主机名称如"www.baidu.com",因为这样好记。当我们写主机名的时候是不是要把它翻译成ip地址才能去访问这台主机?到哪去翻译IP地址呢?想要将主机翻译成ip地址需要域名解析,就需要一个DNS域名解析服务器,当有一个网址的时候,浏览器就要先去公网上找一台域名解析服务器,这台服务器上记载的都是一些知名网站的主机名与ip地址的映射关系表。DNS把IP地址返给客户机之后,客户端就再向网站那台主机发请求,而且是发送到主机的8080端口。 如果你用的网是电信的,你没有自己配置的话,那它默认的是走电信的DNS服务器,当然也可以自己配置联通的移动的啊什么的,但是为什么要指定电信联通什么的啊?就是谁离我近我走谁,人家美国也有个DNS你走美国的也没问题,但是麻烦在哪呢?比如说你就想访问下百度,结果你还得先去美国的公网上那个DNS服务器上查一下你上面有没有记载百度的IP地址啊,它有,就给你了,然后你再去访问百度。没有的话或者时间长的话就解析失败,就显示该页无法显示。 但是http://127.0.0.1:8080 怎么和http://localhost:8080怎么是相对应的呢?也没连过公网啊,应为他两个的映射关系在本机上的C:\Windows\System32\drivers\etc下的hosts文件里,还可以自己更改。所 以访问网址的时候浏览器其实是现在本机找有没有与那个网址对应的IP,没有的话再去公网找。所以你可以把百度的ip地址与主机名的映射关系写在hosts里在访问百度的话速度会稍微快一点。所以在hostsi设置的话可以屏蔽一些网站。
11、网络架构
网络架构
C/S:Client/Server
客户端,服务端。
特点:
1,需要在客户端和服务端都需要编写软件。
2,维护较麻烦。
好处:可以减轻服务端的压力,如网络游戏。
B/S:Browser/Server
浏览器 ,服务端。
1,客户端不用单独编写软件。
因为客户端用的就是浏览器。
2,对于软件升级,只要考虑服务端即可。
弊端:所有的程序都运行在服务端,客户端的浏览器毕竟解析能力较弱。对游戏等。
推荐阅读
-
黑马学习日记_网络编程篇 java网络编程
-
Java网络编程从入门到精通(19):套接字(Socket)的异常
-
嵌入式学习笔记-linux应用编程和网络编程-3.9 linux网络编程实践
-
从零探索Java网络编程01之 TCP/IP 与 Socket
-
Oracle培训(十五)——Core Java第十五章知识点总结——网络编程
-
[JAVA网络编程]用Socket与网络调试助手(NetAssist)进行TCP通讯过程中遇到的问题
-
Java网络编程——UDP通信原理(超详细解析一看就懂哦!!!)
-
11Java网络编程
-
学习数据结构、图形学、系统编程、网络编程,哪门语言可以同时涵盖它们又能快速实现想法呢?
-
java--网络编程