java学习笔记26

来源:互联网 发布:船 vhf 编程 sdk 编辑:程序博客网 时间:2024/05/21 17:12

1、网络编程


后面讲的内容都集中在传输层和网际层。开发的时候玩的都是应用层。



从顶层最原始的图片,一层一层下来,不断加入发送的信息,传输层协议,网络层IP地址,数据链路层的MAC地址是什么,在物理层转为01010的数据就经过网线传输过去了。

2、网络要素——IP地址



IP名不好记,就可以用主机名来代替。为了区别不同的运用程序就可以用端口号来区别他们,有效端口0-65535个

4、TCP传输控制协议,UDP数据报文协议

UDP只管把数据和地址封装成数据包,就像包裹快递一样,有地址但谁知地址正确与否,不保证能邮对地方。地址不存在的话,数据就丢了(被丢掉了),UDP类似对讲机,你喊话,但对方不开机,你这边说的话就白喊了,相当于数据丢失了。

TCP一定要保证对方在,通过3次握手:第1次、A说:B你在吗?第2次、B说:我在。第3次、A说:好的我知道了。建立了稳定可靠的连接。在使用过程中,对方一断开,这边就不发数据了。生活中的手机打电话就是这个道理,对方不连通接电话,你就没法说。


4、IP对象

InetAddress表示互联网协议(IP)地址。


其实在解析地址时先经过本地的hosts文件来查找(和DNS服务器的功能类似,也是提供地址查询),查不到后才去指定的DNS服务器上查找信息。


当你想屏蔽某一个网站时

把那个网站名字写到hosts文件里,让它对应本机IP127.0.0.1,每次访问,先经过hosts解析,就访问成本地了,无法访问指定的网站。


7、UDP协议

socket(套接字)插座,通信线线要插到两端的端口插座上才能通信。如果数据是船只的话,socket也可以理解为港口。不同的协议对应的socket类型不同。

DatagramPacket包对象,分为发送和接收两种,因为发送包的里面需要包含信息和地址,而接收装数据用的包不需要地址

下面是UDP的发送端和接收端的收发数据的写法



在接收到数据包后,由于里面包含多种信息,源地址信息,目的地址信息,数据等,直接接收无法分清里面的数据,但是数据包最清楚里面哪是哪,所以用数据包来接收最合理。

下图中接收数据包对象dp.getAddress()返回的是IP对象,所以还可以继续调用函数,dp.getAddress().getHostAddress()就是在得到IP对象后再得到其主机的字符串形式的数字ip地址。

接收端的receive()方法是阻塞式的,接收不到,就在那里一直等待。

发送端程序:


个人感觉:在发送的时候,想发送给对方的关键是要找到对方的IP地址和对方接收(显示)这些信息的程序所占的端口号(注意:每个程序想要通信都必须占有一个端口号),上面的程序因为要发给本机,所以发送的目的IP地址就是本机的IP地址,我们这里说要发给60001端口,是因为在接收的时候就是用Eclipse程序新开的用来显示接收信息的控制台窗口所占的端口就是60001(在后面的接收端程序中我们指定了,接收端用这个端口),但是在发送端发送信息时并没有指定端口,所以就是系统给发送端的Eclipse程序随机分配了一个没有占用的端口57490,供发送信息用,显示的发送信息自然是本机的IP。

在实验的时候应该让接收端先运行,然后再发送信息。否则发过来的信息会无人接收。

8、收端程序如下


9、上面是收和发分开,但是我们可以写在一个程序中,当然要保证两个同事运行,需要多线程技术。

192.168.1是网络位,最后面的一位是IP位。0-255,但是0不能用,0相当于代表192.168.1.这个网段,不是正常的IP,而192.168.1.255也不是IP地址,而是广播地址,如果把目的IP设为255,那么192.168.1.网段的所有IP都会收到信息,有效的ip地址从192.168.1.1到192.168.1.254


群聊的程序就要求里面的IP设为192.168.1.255,这样就可以广播。实现每台机子上都能群聊,和qq群的感觉很像。

总的聊天程序ChatDemo如下:


发送类如下:


接收类如下:

10、UDP时都是用的DatagramSocket对象,只分收发两种。但是TCP时就不同了,分为客户端Socket和服务器端ServerSocket两种。

SocketAddress类就是把IP地址和端口好封装成一体,统为地址对象。可以用Socket(IP,端口号)直接ok,也可以Socket(),在调用connect(SocketAddress对象),

当TCP连接通道建立好之后也即Socket(IP,端口号),就相当于有了一个总流(包括输入输出流)供数据在上面传输(系统底层建立的),简称外iSocket流。

你输入:www.sina.com,cn相当于告诉新浪服务器把你的网址给我发过来。

Socket的专业名称就是套接字。得到输入流和输出流需要调用Socket的函数getOutPutStream()和getInputStream()来实现获得输出输入流。

从客户端写到服务器是用输出流。Socket流一关,由Socket获得的输入输出流自然也相当于关了。


11、建立TCP服务端

通过IP可以找到一个主机,但是无法找到主机上的特定程序,这是就需要给程序指定端口号(也成为程序监听端口号)



TCP客户端程序如下图:


当两个客户端连接到服务器上时,客户端1给服务器发过来的信息,服务器如何正确回复1,而不是回复成客户端2?原因在于回复1用的是1的流通道,回复2用的是2的流通道,各走各的路,就不会混淆。具体是:服务器获取C1对象,再接着C1的流就可以了。

因为服务器的连接又有上限,所以服务端一定断开,客户端也要断,这样才能让新的客户端让接进来。

服务端的程序如下所示:


12、TCP协议—客户端和服务端交互

客户端的写出相当于服务端的读取,客户端的读相当于服务端的写



下面是能交互的客户端的程序:可以看出客户端不仅有inputStream还有OutputStream


下面是服务端的程序,可以看出也是既有InputStream也有OutputStream


13、Tcp协议的练习—-文本转换客户端

PrintWriter out = new PrintWriter(s.getOutputStream(),true);一个true就保证了能自动刷新



下面是服务端的程序:



59行out.println(line);就是保证把数据写入到写入到服务端去。

由于在服务端值绑定了一个端口,故只能有一个客户端连进来。

15、客户端发送了over结束了,但是服务端也跟着结束了,原因在于当服务端判断输入的是over后,调用s.close(),其实就是在Socket流里植入了结束标记 ,而服务端的输入流还等值读,但是Socket结束返回-1,所以line读的是null,所以服务端也就跳出来while()循环,服务端之后就结束掉了。

之前讲了用PrintWriter(,true)后面在调用println()方法时,具有自动刷新的功能,所以如果把true去掉,并且把println()变成print()那么,就需要在out.print(...)之后再加一句out.flush(),但是还有问题是在服务端是readLine()方法,读到回车符号才会换行,但是改成out.print(...)之后还要在里面加上\r\n,也即写成out.print(。。。。+“\r\n”)否则服务端无法返回字符。

一旦遇到服务端和客户端都停那里不动,一般就是阻塞式方法造成的,print()这是把字符写到InputStream流里去了,但是还需要刷新才能真正写到另一端去。

16、TCP协议练习,上传文本文件

UploadClient的程序如下所示


服务端的程序如下:因为在客户端的时候发送完文件内容,有一句s.shutdownOutput()所以,服务端知道何时该结束了while循环。

注意:BufferedReader或者BufferedWriter的缓冲区默认有8K,当填满之后,会自动刷新。


0 0
原创粉丝点击