Notice: Undefined offset: 70 in/www/wwwroot/wyc/wyc/wyc.phpon line67Java网络编程的套接字一,课程目标网络模型TCP和UDP协议的区别Http协议的实现原理。二、什么是网络
: Undefined offset: 70 in
/www/wwwroot/wyc/wyc/wyc.phpon line
67Java网络编程的套接字
一,课程目标网络模型
TCP和UDP协议的区别
Http协议的实现原理。
二、什么是网络模式?编程的本质是两个设备之间的数据交换。当然,在计算机网络中,设备主要是指计算机。数据传输本身并不难,就是把数据从一个设备发送到另一个设备,然后接收另一个设备的反馈。
现在的网络编程基本都是基于请求/响应模式,即一个设备向另一个设备发送请求数据,然后接收另一个设备的反馈。
在网络编程中,发起连接的程序,即发出第一个请求的程序称为客户端,等待其他程序连接的程序称为服务器端。客户端程序可以在需要的时候启动,而服务器需要一直启动才能一直连接。比如打电话,先拨的人类似于客户端,接电话的人必须保持电话畅通,类似于服务端。
一旦建立了连接,客户端和服务器就可以传输数据,它们的身份是等同的。
在一些程序中,程序同时具有客户端和服务器端的功能,最常见的软件是BT和emule。
先说如何建立连接,如何发送数据。
2.1.IP地址和域名
在现实生活中,如果你想打电话,你需要知道相应人的电话号码,如果你想寄信,你需要知道收件人的地址。网络中也是如此。如果您需要知道设备的位置,您需要使用设备的IP地址。具体的连接过程是通过硬件实现的,程序员不需要太多的关心。
IP地址是一个规则。现在用的是IPv4,由0到255之间的四个数字组成。当存储在计算机中时,它只需要四个字节。在计算机中,IP地址被分配给网卡,每个网卡都有一个唯一的IP地址。如果一台计算机有多个网卡,则该计算机有多个不同的IP地址,并且在同一个网络中IP地址不能相同。IP地址的概念类似于电话号码和身份证的概念。
因为IP地址不太好记,所以专门创造了域名的概念,就是给IP取一个单字符的名字,比如163.com、Sina.com。IP和域名有一定的对应关系。如果你把IP地址和ID号做比较,那么域名就是你的名字。
实际上,网络中只有IP地址可以用于数据传输,所以在传输之前,需要将域名转换成IP,这是由一个叫做DNS的服务器来完成的。
因此,在网络编程中,可以使用IP或域名来标识网络上的设备。
2.2、港口的概念
为了在一个设备上运行多个程序,端口的概念是人为设计的。类似的例子还有公司内部分机号码。
规定一个设备有216个端口,即65536个端口,每个端口对应一个唯一的程序。每个网络程序,无论是客户端还是服务器,都对应一个或多个特定的端口号。因为0-1024大部分被操作系统占用,所以实际编程中一般使用1024之后的端口号。
使用端口号,您可以找到设备上的唯一程序。
所以如果你需要和一台电脑建立连接,你只需要知道IP地址或者域名,但是如果你想和那台电脑上的一个程序交换数据,你还必须知道那个程序使用的端口号。
总结
网络编程就是用IP地址,或者域名,端口连接到另一台计算机上相应的程序,按照规定的协议(数据格式)交换数据。在实际编程中,已经在语言层面实现了建立连接、发送和接收数据,更多的工作是设计协议,编写生成和分析数据的代码,然后将数据转换成逻辑结构显示或控制逻辑。
对于初学者,或者是从未接触过网络编程的程序员来说,会认为网络编程所涉及的知识非常高深,难度很大。其实这是一个误区。当你熟悉了你的语法,基本的网络编程现在已经实现的极其简单了。
三。网络模型图四。套接字入门4.1.什么是插座?
套接字是为网络服务提供的一种机制。
通信两端都有Sokcet。
网络其实就是Sokcet之间的交流。
数据通过IO在两个Sokcet之间传输。
4.2.TCP和UDP之间的概念差异:
Udp: a,面向无连接,将数据和源封装成数据包,不需要建立连接。
b、每个数据报的大小在64k的限制内。
c,因为没有连接,所以是不可靠的协议。
d、不需要建立连接,速度快。
TCP: A .建议连接形成一个通道进行数据传输。
b、大量数据以字节流的形式在连接中传输。
c三次握手是完成连接的可靠协议。
d连接必须建立,m效率会稍低。
4.3.UDP协议
课程案例通过UDP协议实现,客户端和服务器端进行传输。
UDP服务器端代码
class UdpServer {public static void main(String[] args) throws IOException {System.out.println("udp接受数据启动.......");DatagramSocket ds = new DatagramSocket(8080);byte[] buf = new byte[1024];DatagramPacket dp = new DatagramPacket(buf, buf.length);// 阻塞效果ds.receive(dp);System.out.println("来源:"+dp.getAddress().getHostAddress()+",port:"+dp.getPort());String str = new String(dp.getData(),0,dp.getLength());System.out.println("客户端发送数据:"+str);ds.close();}}
UDP客户端代码
public class UdpClient {public static void main(String[] args) throws IOException {System.out.println("udp 发送数据");DatagramSocket ds = new DatagramSocket();String str = "客户端发送数据....";byte[] strByte = str.getBytes();DatagramPacket dp = new DatagramPacket(strByte, strByte.length, InetAddress.getByName("192.168.1.3"), 8080);ds.send(dp);ds.close();}}
4.3.TCP协议
TCP握手协议
在TCP/IP协议中,TCP协议使用三次握手来建立连接。
第一次握手:当连接建立后,客户端向服务器发送一个SYN包(SYN=J),进入SYN_SEND状态,等待服务器的确认;
第二次握手:服务器收到SYN包时,必须确认客户端的SYN(ACK=J+1),并自己发送一个SYN包(SYN=K),即SYN+ACK包。此时服务器处于V状态;
三次握手:客户端从服务器接收SYN+ACK包,并向服务器发送确认包ACK(ACK=K+1)。发送这个数据包后,客户端和服务器进入建立状态,完成三次握手。
三次握手完成,客户端和服务器开始传输数据。
四次分手:
因为TCP连接是全双工的,所以每个方向都必须单独关闭。这个原理就是当一方完成了它的数据传输任务,就可以发送一个FIN来终止这个方向的连接。接收到FIN只是表示这个方向没有数据流,TCP连接在接收到FIN后仍然可以发送数据。第一个关闭方将执行主动关闭,而另一方将执行被动关闭。
(1)客户端A发送FIN以关闭从客户端A到服务器b的数据传输
(2)服务器B接收到这个FIN,它发回一个ack,确认序列号是接收到的序列号加1。像SYN一样,一个鳍会占用一个序列号。
(3)服务器B关闭与客户端A的连接,并向客户端A发送FIN。
(4)客户端A发回ack消息进行确认,并将确认序列号设置为接收到的序列号加1。
1.为什么建立连接的协议是三次握手,而关闭连接是四次握手?
这是因为服务器处于LISTEN状态的SOCKET在收到SYN消息的连接请求后,可以在一个消息中发送ACK和SYN(ACK起响应的作用,SYN起同步的作用)。
但是当连接关闭,收到对方的FIN消息通知时,只表示对方没有数据发送给你;但是你的数据可能不会全部发送给对方,所以你可能会也可能不会马上关闭SOCKET,也就是你可能需要发送一些数据给对方,然后再发送FIN消息给对方,表示你同意现在关闭连接,所以这里的ACK消息和FIN消息大多数情况下是分开发送的。
2.为什么TIME_WAIT状态还需要等待2MSL才能回到关闭状态?
这是因为,虽然双方都同意关闭连接,并且协调发送了四个握手消息,但是直接返回关闭状态是合理的(就像从SYN_SEND状态建立状态一样);但是,我们要假设网络是不可靠的,你不能保证你发的最后一条ACK消息会被对方收到。所以对方LAST_ACK状态的SOCKET由于超时后还没有收到ACK消息,可能会重新发送FIN消息,所以这个TIME_WAIT状态的作用就是重新发送可能丢失的ACK消息。
4.3.1服务器端代码
public class TcpServer { public static void main(String[] args) throws IOException {System.out.println("socket服务器端启动....");ServerSocket serverSocket = new ServerSocket(8080); //获取客户端对象Socket accept = serverSocket.accept();InputStream inputStream = accept.getInputStream();byte[] buf= new byte[1024];int len=inputStream.read(buf);String str =new String(buf,0,len);System.out.println("str:"+str);serverSocket.close();}}
客户代码
System.out.println("socket启动....");Socket s = new Socket("192.168.1.3", 8080);OutputStream outputStream = s.getOutputStream();outputStream.write("我是客戶端....".getBytes());s.close();