渭南软件开发,番禺网站建设优化推广,wordpress创建自定义分类法,浙江瑞通建设集团网站一#xff1a;网络编程基础
1.1 网络资源
所谓的网络资源#xff0c;其实就是在网络中可以获取的各种数据资源#xff0c;而所有的网络资源#xff0c;都是通过网络编程来进行数据传输的。 用户在浏览器中#xff0c;打开在线视频网站#xff0c;如优酷看视频#xff…一网络编程基础
1.1 网络资源
所谓的网络资源其实就是在网络中可以获取的各种数据资源而所有的网络资源都是通过网络编程来进行数据传输的。 用户在浏览器中打开在线视频网站如优酷看视频实质是通过网络获取到网络上的一个视频资源与本地打开视频文件类似只是视频文件这个资源的来源是网络。 那么我们怎么将这些网络资源在不同的设备上进行传输呢答案是网络编程
1.2 网络编程
网络编程指网络上的主机通过不同的进程以编程的方式实现网络通信或称为网络数据传输。 当然我们只要满足进程不同就行所以即便是同一个主机只要是不同进程基于网络来传输数据也属于网络编程。
特殊的对于开发来说在条件有限的情况下一般也都是在一个主机中运行多个进程来完成网络编程。
但是我们一定要明确我们的目的是提供网络上不同主机基于网络来传输数据资源
进程A编程来获取网络资源进程B编程来提供网络资源
1.3网络编程中的基本概念
1.3.1 发送端和接收端
在一次网络数据传输时
发送端数据的发送方进程称为发送端。发送端主机即网络通信中的源主机。接收端数据的接收方进程称为接收端。接收端主机即网络通信中的目的主机。收发端发送端和接收端两端也简称为收发端。
注意发送端和接收端只是相对的只是一次网络数据传输产生数据流向后的概念。 1.3.2 请求和响应
一般来说获取一个网络资源涉及到两次网络数据传输
第一次请求数据的发送第二次响应数据的发送。
好比在快餐店点一份炒饭先要发起请求点一份炒饭再有快餐店提供的对应响应提供一份炒饭 1.3.3 客户端和服务端
服务端在常见的网络数据传输场景下把提供服务的一方进程称为服务端可以提供对外服务。
客户端获取服务的一方进程称为客户端。
对于服务来说一般是提供
客户端获取服务资源 客户端保存资源在服务端 1.3.4 常见的客户端服务端模型
最常见的场景客户端是指给用户使用的程序服务端是提供用户服务的程序
客户端先发送请求到服务端服务端根据请求数据执行相应的业务处理服务端返回响应发送业务处理结果客户端根据响应数据展示处理结果展示获取的资源或提示保存资源的处理结果 二Socket套接字
Socket套接字是由系统提供用于网络通信的技术是基于TCP/IP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程。
Socket套接字主要针对传输层协议划分为如下三类
流套接字使用传输层TCP协议数据报套接字使用传输层UDP协议原始套接字
TCP即Transmission Control Protocol传输控制协议传输层协议。
UDP即User Datagram Protocol用户数据报协议传输层协议。
原始套接字用于自定义传输层协议用于读写内核没有处理的IP协议数据。
2.1 在java中如何一次发送及接收UDP数据报
对于UDP协议来说具有无连接面向数据报的特征即每次都是没有建立连接并且一次发送全部数据报一次接收全部的数据报。
java中使用UDP协议通信主要基于 DatagramSocket 类来创建数据报套接字并使用DatagramPacket 作为发送或接收的UDP数据报。对于一次发送及接收UDP数据报的流程如下 以上只是一次发送端的UDP数据报发送及接收端的数据报接收并没有返回的数据。也就是只有请求没有响应。对于一个服务端来说重要的是提供多个客户端的请求处理及响应流程如下 2.2 Socket编程注意事项 客户端和服务端开发时经常是基于一个主机开启两个进程作为客户端和服务端但真实的场景一般都是不同主机。注意目的IP和目的端口号标识了一次数据传输时要发送数据的终点主机和进程Socket编程我们是使用流套接字和数据报套接字基于传输层的TCP或UDP协议但应用层协议也需要考虑这块我们在后续来说明如何设计应用层协议。
关于端口被占用的问题如果一个进程A已经绑定了一个端口再启动一个进程B绑定该端口就会报错这种情况也叫端口被占用。对于java进程来说端口被占用的常见报错信息如下 此时需要检查进程B绑定的是哪个端口再查看该端口被哪个进程占用。以下为通过端口号查进程的方式
在cmd输入 netstat -ano | findstr 端口号 则可以显示对应进程的pid。如以下命令显示了8888进程的pid 在任务管理器中通过pid查找进程 解决端口被占用的问题如果占用端口的进程A不需要运行就可以关闭A后再启动需要绑定该端口的进程B如果需要运行A进程则可以修改进程B的绑定端口换为其他没有使用的端口。
三UDP数据报套接字编程
3.1 DatagramSocket API
DatagramSocket 是UDP Socket用于发送和接收UDP数据报。
DatagramSocket 构造方法
方法签名方法说明DatagramSocket()创建一个UDP数据报套接字的Socket绑定到本机任意一个随机端口DatagramSocket(int port)创建一个UDP数据报套接字的Socket绑定到本机指定的端口
DatagramSocket 方法
方法签名方法说明void receive(DatagramPacket p)从此套接字接收数据报如果没有接收到数据报该方法会阻塞等待void send(DatagramPacket p)从此套接字发送数据报包不会阻塞等待直接发送void close()关闭此数据报套接字
3.2 DatagramPacket API
DatagramPacket是UDP Socket发送和接收的数据报。
DatagramPacket 构造方法
方法签名方法说明DatagramPacket(byte[] buf, int length)构造一个DatagramPacket以用来接收数据报接收的数据保存在字节数组第一个参数buf中接收指定长度第二个参数lengthDatagramPacket(byte[] buf, int offset, int length, SocketAddress address)构造一个DatagramPacket以用来发送数据报发送的数据为字节数组第一个参数buf中从0到指定长度第二个参数length。address指定目的主机的IP和端口号
DatagramPacket 方法
方法签名方法说明InetAddress.getAddress()从接收的数据报中获取发送端主机IP地址或从发送的数据报中获取接收端主机IP地址InetAddress.getPort()从接收的数据报中获取发送端主机的端口号或从发送的数据报中获取接收端主机端口号DatagramPacket.getData()获取数据报中的数据
构造UDP发送的数据报时需要传入 SocketAddress 该对象可以使用 InetSocketAddress 来创建。
3.3 InetSocketAddress API
InetSocketAddress SocketAddress 的子类 构造方法
方法签名方法说明InetSocketAddress(InetAddress addr, int port)创建一个Socket地址包含IP地址和端口号
3.4 案例演示
一发一收无响应
3.4.1 UDP服务端
package org.example.udp.demo1;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Arrays;
public class UdpServer {//服务器socket要绑定固定的端口private static final int PORT 8888;public static void main(String[] args) throws IOException {// 1.创建服务端DatagramSocket指定端口可以发送及接收UDP数据报DatagramSocket socket new DatagramSocket(PORT);//不停的接收客户端udp数据报while (true){// 2.创建数据报用于接收客户端发送的数据byte[] bytes new byte[1024];//1m1024kb, 1kb1024byte, UDP最多
64k包含UDP首部8byteDatagramPacket packet new DatagramPacket(bytes, bytes.length);System.out.println(------------------------------------------------
---);System.out.println(等待接收UDP数据报...);// 3.等待接收客户端发送的UDP数据报该方法在接收到数据报之前会一直阻塞接收到数据报以后DatagramPacket对象包含数据bytes和客户端ip、端口号socket.receive(packet);System.out.printf(客户端IP%s%n,packet.getAddress().getHostAddress());System.out.printf(客户端端口号%s%n, packet.getPort());System.out.printf(客户端发送的原生数据为%s%n, Arrays.toString(packet.getData()));System.out.printf(客户端发送的文本数据为%s%n, new String(packet.getData()));}}
}运行后服务端就启动了控制台输出如下 等待接收UDP数据报…
可以看出此时代码是阻塞等待在 socket.receive(packet) 代码行直到接收到一个UDP数据报。
3.4.2 UDP客户端
package org.example.udp.demo1;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
public class UdpClient {// 服务端socket地址包含域名或IP及端口号private static final SocketAddress ADDRESS new
InetSocketAddress(localhost, 8888);public static void main(String[] args) throws IOException {// 4.创建客户端DatagramSocket开启随机端口就行可以发送及接收UDP数据报DatagramSocket socket new DatagramSocket();// 5-1.准备要发送的数据byte[] bytes hello world!.getBytes();// 5-2.组装要发送的UDP数据报包含数据及发送的服务端信息服务器IP端口号DatagramPacket packet new DatagramPacket(bytes, bytes.length,ADDRESS);// 6.发送UDP数据报socket.send(packet);}
}客户端启动后会发送一个hello world! 的字符串到服务端在服务端接收后控制台输出内容如下 等待接收UDP数据报… 客户端IP127.0.0.1 客户端端口号57910 客户端发送的原生数据为[104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33, 0, 0, 0, …此处省略很多0] 客户端发送的文本数据为hello world! 等待接收UDP数据报…
从以上可以看出发送的UDP数据报假设发送的数据字节数组长度为M在接收到以后假设接收的数据字节数组长度为N
如果NM则接收的byte[]字节数组中会有很多初始化byte[]的初始值0转换为字符串就是空白字符如果NM则会发生数据部分丢失可以自己尝试把接收的字节数组长度指定为比发送的字节数组长度更短。
要解决以上问题就需要发送端和接收端双方约定好一致的协议如规定好结束的标识或整个数据的长度。
四TCP流套接字编程
4.1 ServerSocket API
ServerSocket 是创建TCP服务端Socket的API。
ServerSocket 构造方法
方法签名方法说明ServerSocket(int port)创建一个服务端流套接字Socket并绑定到指定端口。
ServerSocket 方法
方法签名方法说明Socket accept()开始监听指定端口创建时绑定的端口有客户端连接后返回一个服务端Socket对象并基于该Socket建立与客户端的连接否则阻塞等待void close()关闭此套接字
4.2 Socket API
Socket 是客户端Socket或服务端中接收到客户端建立连接accept方法的请求后返回的服务端Socket。
不管是客户端还是服务端Socket都是双方建立连接以后保存的对端信息及用来与对方收发数据的。
Socket 构造方法
方法签名方法说明Socket(String host, int port)创建一个客户端流套接字Socket并与对应IP的主机上对应端口的进程建立连接
Socket 方法
方法签名方法说明getInetAddress()返回套接字所连接的地址getInputStream()返回此套接字的输入流getOutputStream()返回此套接字的输出流
4.3 TCP中的长短连接
TCP发送数据时需要先建立连接什么时候关闭连接就决定是短连接还是长连接
短连接每次接收到数据并返回响应后都关闭连接即是短连接。也就是说短连接只能一次收发数据。长连接不关闭连接一直保持连接状态双方不停的收发数据即是长连接。也就是说长连接可以多次收发数据。
对比以上长短连接两者区别如下 建立连接、关闭连接的耗时短连接每次请求、响应都需要建立连接关闭连接而长连接只需要第一次建立连接之后的请求、响应都可以直接传输。相对来说建立连接关闭连接也是要耗时的长连接效率更高。 主动发送请求不同短连接一般是客户端主动向服务端发送请求而长连接可以是客户端主动发送请求也可以是服务端主动发。 两者的使用场景有不同短连接适用于客户端请求频率不高的场景如浏览网页等。长连接适用于客户端与服务端通信频繁的场景如聊天室实时游戏等。
扩展了解 基于BIO同步阻塞IO的长连接会一直占用系统资源。对于并发要求很高的服务端系统来说这样的消耗是不能承受的。
由于每个连接都需要不停的阻塞等待接收数据所以每个连接都会在一个线程中运行。
一次阻塞等待对应着一次请求、响应不停处理也就是长连接的特性一直不关闭连接不停的处理请求。
实际应用时服务端一般是基于NIO即同步非阻塞IO来实现长连接性能可以极大的提升。
4.4 案例演示
一发一收短连接
以下为一个客户端一次数据发送和服务端多次数据接收一次发送一次接收可以接收多次即只有客户端请求但没有服务端响应的示例
4.4.1 TCP服务端
package org.example.tcp.demo1;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {//服务器socket要绑定固定的端口private static final int PORT 8888;public static void main(String[] args) throws IOException {// 1.创建一个服务端ServerSocket用于收发TCP报文ServerSocket server new ServerSocket(PORT);// 不停的等待客户端连接while(true) {System.out.println(---------------------------------------------------);System.out.println(等待客户端建立TCP连接...);// 2.等待客户端连接注意该方法为阻塞方法Socket client server.accept();System.out.printf(客户端IP%s%n,client.getInetAddress().getHostAddress());System.out.printf(客户端端口号%s%n, client.getPort());// 5.接收客户端的数据需要从客户端Socket中的输入流获取System.out.println(接收到客户端请求);InputStream is client.getInputStream();// 为了方便获取字符串内容可以将以上字节流包装为字符流BufferedReader br new BufferedReader(new InputStreamReader(is,UTF-8));String line;// 一直读取到流结束TCP是基于流的数据传输一定要客户端关闭Socket输出流才表示服务端接收IO输入流结束while ((line br.readLine()) ! null) {System.out.println(line);}// 6.双方关闭连接服务端是关闭客户端socket连接client.close();}}
}运行后服务端就启动了控制台输出如下 等待客户端建立TCP连接…
可以看出此时代码是阻塞等待在 server.accept() 代码行直到有新的客户端申请建立连接。
4.4.2 TCP客户端
package org.example.tcp.demo1;
import java.io.*;
import java.net.Socket;
public class TcpClient {//服务端IP或域名private static final String SERVER_HOST localhost;//服务端Socket进程的端口号private static final int SERVER_PORT 8888;public static void main(String[] args) throws IOException {// 3.创建一个客户端流套接字Socket并与对应IP的主机上对应端口的进程建立连接Socket client new Socket(SERVER_HOST, SERVER_PORT);// 4.发送TCP数据是通过socket中的输出流进行发送OutputStream os client.getOutputStream();// 为了方便输出字符串作为发送的内容可以将以上字节流包装为字符流PrintWriter pw new PrintWriter(new OutputStreamWriter(os, UTF-8));// 4-1.发送数据pw.println(hello world!);// 4-2.有缓冲区的IO操作真正传输数据需要刷新缓冲区pw.flush();// 7.双方关闭连接客户端关闭socket连接client.close();}
}客户端启动后会发送一个hello world! 的字符串到服务端在服务端接收后控制台输出内容如下 等待客户端建立TCP连接… 客户端IP127.0.0.1 客户端端口号51118 接收到客户端请求 hello world! 等待客户端建立TCP连接…
以上客户端与服务端建立的为短连接每次客户端发送了TCP报文及服务端接收了TCP报文后双方都会关闭连接。
五再谈协议
以上我们实现的UDP和TCP数据传输除了UDP和TCP协议外程序还存在应用层自定义协议可以想想分别都是什么样的协议格式。
对于客户端及服务端应用程序来说请求和响应需要约定一致的数据格式
客户端发送请求和服务端解析请求要使用相同的数据格式。服务端返回响应和客户端解析响应也要使用相同的数据格式。请求格式和响应格式可以相同也可以不同。约定相同的数据格式主要目的是为了让接收端在解析的时候明确如何解析数据中的各个字段。可以使用知名协议广泛使用的协议格式如果想自己约定数据格式就属于自定义协议。
5.1 封装/分用 vs 序列化/反序列化
一般来说在网络数据传输中发送端应用程序发送数据时的数据转换如java一般就是将对象转换为某种协议格式即对发送数据时的数据包装动作来说
如果是使用知名协议这个动作也称为封装如果是使用小众协议包括自定义协议这个动作也称为序列化一般是将程序中的对象转换为特定的数据格式。
接收端应用程序接收数据时的数据转换即对接收数据时的数据解析动作来说
如果是使用知名协议这个动作也称为分用如果是使用小众协议包括自定义协议这个动作也称为反序列化一般是基于接收数据特定的格式转换为程序中的对象 文章转载自: http://www.morning.lhrcr.cn.gov.cn.lhrcr.cn http://www.morning.neletea.com.gov.cn.neletea.com http://www.morning.hqmfn.cn.gov.cn.hqmfn.cn http://www.morning.qgjgsds.com.cn.gov.cn.qgjgsds.com.cn http://www.morning.qwgct.cn.gov.cn.qwgct.cn http://www.morning.smdkk.cn.gov.cn.smdkk.cn http://www.morning.xjnw.cn.gov.cn.xjnw.cn http://www.morning.nqmdc.cn.gov.cn.nqmdc.cn http://www.morning.hmktd.cn.gov.cn.hmktd.cn http://www.morning.wqbzt.cn.gov.cn.wqbzt.cn http://www.morning.qsy36.cn.gov.cn.qsy36.cn http://www.morning.yfphk.cn.gov.cn.yfphk.cn http://www.morning.nkkpp.cn.gov.cn.nkkpp.cn http://www.morning.lxctl.cn.gov.cn.lxctl.cn http://www.morning.wdrxh.cn.gov.cn.wdrxh.cn http://www.morning.rwmq.cn.gov.cn.rwmq.cn http://www.morning.mfjfh.cn.gov.cn.mfjfh.cn http://www.morning.qsyyp.cn.gov.cn.qsyyp.cn http://www.morning.rfmzc.cn.gov.cn.rfmzc.cn http://www.morning.trsdm.cn.gov.cn.trsdm.cn http://www.morning.dnmwl.cn.gov.cn.dnmwl.cn http://www.morning.mbfj.cn.gov.cn.mbfj.cn http://www.morning.mlhfr.cn.gov.cn.mlhfr.cn http://www.morning.tfwr.cn.gov.cn.tfwr.cn http://www.morning.jypqx.cn.gov.cn.jypqx.cn http://www.morning.clxpp.cn.gov.cn.clxpp.cn http://www.morning.lbxhy.cn.gov.cn.lbxhy.cn http://www.morning.3dcb8231.cn.gov.cn.3dcb8231.cn http://www.morning.nxwk.cn.gov.cn.nxwk.cn http://www.morning.zplzj.cn.gov.cn.zplzj.cn http://www.morning.tnjz.cn.gov.cn.tnjz.cn http://www.morning.syglx.cn.gov.cn.syglx.cn http://www.morning.xrksf.cn.gov.cn.xrksf.cn http://www.morning.ckdgj.cn.gov.cn.ckdgj.cn http://www.morning.mlzyx.cn.gov.cn.mlzyx.cn http://www.morning.gxtbn.cn.gov.cn.gxtbn.cn http://www.morning.sgnjg.cn.gov.cn.sgnjg.cn http://www.morning.smdkk.cn.gov.cn.smdkk.cn http://www.morning.mjglk.cn.gov.cn.mjglk.cn http://www.morning.slfmp.cn.gov.cn.slfmp.cn http://www.morning.qfcnp.cn.gov.cn.qfcnp.cn http://www.morning.lkwyr.cn.gov.cn.lkwyr.cn http://www.morning.wjmb.cn.gov.cn.wjmb.cn http://www.morning.thwhn.cn.gov.cn.thwhn.cn http://www.morning.pjyrl.cn.gov.cn.pjyrl.cn http://www.morning.nrpp.cn.gov.cn.nrpp.cn http://www.morning.dfndz.cn.gov.cn.dfndz.cn http://www.morning.cwknc.cn.gov.cn.cwknc.cn http://www.morning.hgsmz.cn.gov.cn.hgsmz.cn http://www.morning.rkwlg.cn.gov.cn.rkwlg.cn http://www.morning.bdtpd.cn.gov.cn.bdtpd.cn http://www.morning.bklhx.cn.gov.cn.bklhx.cn http://www.morning.nxkyr.cn.gov.cn.nxkyr.cn http://www.morning.dmtld.cn.gov.cn.dmtld.cn http://www.morning.swimstaracademy.cn.gov.cn.swimstaracademy.cn http://www.morning.zzaxr.cn.gov.cn.zzaxr.cn http://www.morning.yxlhz.cn.gov.cn.yxlhz.cn http://www.morning.pwqyd.cn.gov.cn.pwqyd.cn http://www.morning.ttrdr.cn.gov.cn.ttrdr.cn http://www.morning.mgwdp.cn.gov.cn.mgwdp.cn http://www.morning.xtlty.cn.gov.cn.xtlty.cn http://www.morning.kxscs.cn.gov.cn.kxscs.cn http://www.morning.ydfr.cn.gov.cn.ydfr.cn http://www.morning.bfcrp.cn.gov.cn.bfcrp.cn http://www.morning.rwlnk.cn.gov.cn.rwlnk.cn http://www.morning.kehejia.com.gov.cn.kehejia.com http://www.morning.jrkzk.cn.gov.cn.jrkzk.cn http://www.morning.gbkkt.cn.gov.cn.gbkkt.cn http://www.morning.jtcq.cn.gov.cn.jtcq.cn http://www.morning.plxhq.cn.gov.cn.plxhq.cn http://www.morning.ykxnp.cn.gov.cn.ykxnp.cn http://www.morning.fqssx.cn.gov.cn.fqssx.cn http://www.morning.zgqysw.cn.gov.cn.zgqysw.cn http://www.morning.mglqf.cn.gov.cn.mglqf.cn http://www.morning.drswd.cn.gov.cn.drswd.cn http://www.morning.mmjqk.cn.gov.cn.mmjqk.cn http://www.morning.yxgqr.cn.gov.cn.yxgqr.cn http://www.morning.pqkgb.cn.gov.cn.pqkgb.cn http://www.morning.fswml.cn.gov.cn.fswml.cn http://www.morning.rshkh.cn.gov.cn.rshkh.cn