赞
踩
目录
想要进行网络编程,都需要使用到系统的API。本质上都是传输层提供的。传输层涉及到的协议主要有两个。TCP和UDP,他俩的api差异很大。
TCP和UDP都是Socket套接字针对的传输层协议划。
Socket 套接字,是由系统提供用于网络通信的技术,是基于 TCP/IP 协议的网络通信的基本操作单元。基 于Socket 套接字的网络程序开发就是网络编程
1.有连接2.可靠传输3.面向字节流4.有接收缓冲区,也有发送缓冲区5.大小不限
数据报套接字:使用传输层UDP协议
以下为UDP的特点
1.无连接2.不可靠传输3.面向数据报4.有接收缓冲区,无发送缓冲区5.大小受限:一次最多传输 64k
(1)有/无 连接
网络中谈到的连接,本质上是通信双方各自保存双方信息。
有连接是通信双方都要同意。如:微信发电话。
无连接是收方无论是否同意,都会收到信息。如:微信发消息。
(2)可/不可 靠传输
由于网络上存在的异常情况非常的多,无法保证网络数据100%通信成功。
可靠传输 是指发送方知道自己发送的信息是否成功送达。反之不知道则是不可靠传输
(3) 面向数据报/字节流
指的是网络中传输的基本单位是数据报/字节流。
DatagramSocket 是UDP Socket,用于发送和接收UDP数据报。
socket 文件抽象了“网卡”这样的硬件设备。
(2)DatagramSocket 方法:
DatagramPacket是UDP Socket发送和接收的数据报。
(2)DatagramPacket 方法:
构造UDP发送的数据报时,需要传入 SocketAddress ,该对象可以使用 InetSocketAddress 来创建。
什么叫回显客户端与与服务器呢?
其实就是:客户端向服务端发送请求,一般来说我们的服务端会对我们发送的请求进行处理,我们这里为了简单,就省略里面的处理过程,只实现将请求重新发回客户端,不做任何处理。
1.需要创建一个DatagramSocket对象,因为需要操作网卡。
代码:
- public class UdpEchoServer {
- private DatagramSocket socket=null;
-
- public UdpEchoServer(int port) throws SocketException {
- socket=new DatagramSocket(port);
- }
- }
代码说明:
(1)socket=new DatagramSocket(port);
在运行一个服务器的时候,通常会手动指定一个端口号。
补:一个主机上的端口号,只能被一个进程绑定,但一个进程可以绑定多个端口号。
(2)throws SocketException
通常表示socket创建失败。
比如:端口号已经被别的进程占用了。
工作内容:
1. 读取请求并解析
2. 根据请求计算响应 (对于 回显服务器来说, 这一步啥都不用做)
3. 把响应返回到客户端.
4.打印日志
代码:
- import java.io.IOException;
- import java.net.*;
-
-
- public class UdpEchoServer {
- private DatagramSocket socket = null;
-
- public UdpEchoServer(int port) throws SocketException {
- socket = new DatagramSocket(port);
- }
-
- public void start() throws IOException {
- System.out.println("服务器启动");
- while (true) {
- DatagramPacket requestpacket = new DatagramPacket(new byte[4096], 4096);
- socket.receive(requestpacket);
- String request = new String(requestpacket.getData(), 0, requestpacket.getLength());
- String response = process(request);
- DatagramPacket responsepacket = new DatagramPacket(response.getBytes(), response.getBytes().length, requestpacket.getSocketAddress());
- socket.send(responsepacket);
- // 打印日志
- System.out.printf("[%s:%d] req: %s, resp: %s\n", requestpacket.getAddress().toString(),
- requestpacket.getPort(), request, response);
- }
- }
-
- private String process(String request) {
- return request;
- }
- }
代码说明:
1. while (true) {~~~}
对于服务器来说,需要不停的收到请求,返回响应,收到请求,返回响应
2. DatagramPacket requestpacket = new DatagramPacket(new byte[4096], 4096);
(1)byte[4096]->4096 表示的是载荷长度。
这个数组存的是消息正文(应用层数据包)也就是UDP数据包载荷部分。
(2) socket.receive(requestpacket);
如果执行到socket.receive(requestpacket)的时候,还没有客户端发来请求,则会先堵塞等待。
(3 )requestpacket.getSocketAddress()
由于requestpacket是从客户端来的数据报,故得到的InetAddress对象就会包含了客户端的IP和端口号。
代码:
- public static void main(String[] args) throws IOException {
- UdpEchoServer server = new UdpEchoServer(9090);
- server.start();
- }
代码说明:
UdpEchoServer server = new UdpEchoServer(9090);
9090->这个端口号可以指定任何你想要指定的端口号。
代码:
- package network;
-
- import java.io.IOException;
- import java.net.DatagramPacket;
- import java.net.DatagramSocket;
- import java.net.SocketException;
- import java.nio.charset.StandardCharsets;
-
- public class UdpEchoServer {
- private DatagramSocket socket = null;
-
- public UdpEchoServer(int port) throws SocketException {
- socket = new DatagramSocket(port);
- }
-
- // 服务器的启动逻辑.
- public void start() throws IOException {
- System.out.println("服务器启动!");
- while (true) {
- // 每次循环, 就是处理一个请求-响应过程.
- // 1. 读取请求并解析
- DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 4096);
- socket.receive(requestPacket);
- // 读到的字节数组, 转成 String 方便后续的逻辑处理.
- String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
- // 2. 根据请求计算响应 (对于 回显服务器来说, 这一步啥都不用做)
- String response = process(request);
- // 3. 把响应返回到客户端.
- // 构造一个 DatagramPacket 作为响应对象
- DatagramPacket responsePacket = new DatagramPacket(response.getBytes(), response.getBytes().length,
- requestPacket.getSocketAddress());
- socket.send(responsePacket);
-
- // 打印日志
- System.out.printf("[%s:%d] req: %s, resp: %s\n", requestPacket.getAddress().toString(),
- requestPacket.getPort(), request, response);
- }
- }
-
- public String process(String request) {
- return request;
- }
-
- public static void main(String[] args) throws IOException {
- UdpEchoServer server = new UdpEchoServer(9090);
- server.start();
- }
- }
代码:
- import java.io.IOException;
- import java.net.*;
- import java.util.Scanner;
-
- public class UdpEchoClient {
- private DatagramSocket socket = null;
- private String serverIp;
- private int serverPort;
-
- public UdpEchoClient(String serverIp,int serverPort) throws SocketException {
- this.socket = new DatagramSocket();
- this.serverIp = serverIp;
- this.serverPort = serverPort;
- }
- }
代码说明:
(1)this.socket = new DatagramSocket();
客户端这边一般不会手动指定端口好,会让系统自动分配一个端口号。
(2)private String serverIp;
private int serverPort;
客户端需要主动给服务器发送请求,发送请求的前提是知道服务器在哪。
工作内容:
1. 从控制台读取要发送的请求数据.
2. 构造请求并发送
3. 读取服务器的响应.
4. 把响应显示到控制台上
代码:
- public void start() throws IOException {
- System.out.println("客户端启动");
- Scanner scanner = new Scanner(System.in);
- while (true){
- System.out.print("->");
- if(!scanner.hasNext()){
- break;
- }
- String request=scanner.next();
- DatagramPacket requestpacket=new DatagramPacket(request.getBytes(),request.getBytes().length, InetAddress.getByName(serverIp),serverPort);
- socket.send(requestpacket);
- DatagramPacket responsepacket=new DatagramPacket(new byte[4096],4096);
- socket.receive(responsepacket);
- String response=new String(responsepacket.getData(),0,responsepacket.getLength());
- System.out.println(response);
- }
- }
代码说明:
InetAddress.getByName(serverIp)
把数据的单位从字符->字节。
代码:
- public static void main(String[] args) throws IOException {
- UdpEchoClient client = new UdpEchoClient("127.0.0.1", 9090);
- client.start();
- }
代码:
- import java.io.IOException;
- import java.net.*;
- import java.util.Scanner;
-
- public class UdpEchoClient {
- private DatagramSocket socket = null;
- private String serverIp;
- private int serverPort;
-
-
- // 此处 ip 使用的字符串, 点分十进制风格. "192.168.2.100"
- public UdpEchoClient(String serverIp, int serverPort) throws SocketException {
- this.serverIp = serverIp;
- this.serverPort = serverPort;
- socket = new DatagramSocket();
- }
-
- public void start() throws IOException {
- System.out.println("客户端启动");
- Scanner scanner = new Scanner(System.in);
- while (true) {
- // 要做四个事情
- System.out.print("-> "); // 表示提示用户接下来要输入内容.
- // 1. 从控制台读取要发送的请求数据.
- if (!scanner.hasNext()) {
- break;
- }
- String request = scanner.next();
- // 2. 构造请求并发送.
- DatagramPacket requestPacket = new DatagramPacket(request.getBytes(), request.getBytes().length,
- InetAddress.getByName(serverIp), serverPort);
- socket.send(requestPacket);
- // 3. 读取服务器的响应.
- DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);
- socket.receive(responsePacket);
- // 4. 把响应显示到控制台上.
- String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
- System.out.println(response);
- }
- }
-
- public static void main(String[] args) throws IOException {
- UdpEchoClient client = new UdpEchoClient("127.0.0.1", 9090);
- // UdpEchoClient client = new UdpEchoClient("139.155.74.81", 9090);
- client.start();
- }
- }
运行结果:
小结 :
以上为我个人的小分享,如有问题,欢迎讨论!!!
都看到这了,不如关注一下,给个免费的赞
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。