赞
踩
在网络通信协议下,不同计算机上运行的程序,进行的数据传输。
不管是什么场景,都是计算机跟计算机之间通过网络进行数据传输。
什么网络编程?
计算机跟计算机之间通过网络进行数据传输。
常见软件架构有哪些?
CS/BS
通信的软件架构CS1BS的各有什么区别和优缺点
CS:客户端服务端模式需要开发客户端
BS:浏览器服务端模式不需要开发客户端。
CS:适合定制专业化的办公类软件如:IDEA、网游
BS:适合移动互联网应用,可以在任何地方随时访问的系统。
IP
设备在网络中的地址,是唯一的标识。
端口号
应用程序在设备中唯一的标识。
协议
数据在网络中传输的规则,常见的协议有UDP、TCP、http、https、ftp。
网络编程三要素分别是什么?
IP、端口号、协议
网络编程三要素分别表示什么?
IP:设备在网络中的地址,是唯一的标识
端口号:应用程序在设备中唯一的标识。
协议:数据在网络中传输的规则
常见的协议有UDP、TCP、http、https、ftp
全称:Internet Protocol,是互联网协议地址,也称IP地址。
是分配给上网设备的数字标签。
通俗理解 上网设备在网络中的地址,是唯一的
常见的IP分类为IPV4、IPV6
全称:Internet Protocol version4,互联网通信协议第四版。
采用32位地址长度,分成4组
全称:Internet Protocol version6,互联网通信协议第六版。
由于互联网的蓬勃发展,IP地址的需求量愈来愈大,而引PV4的模式下IP的总数是有限的。
采用128位地址长度,分成8组。 2^128
127.0.0.1,也可以是localhost:是回送地址也称本地回环地址,也称本机IP,永远只会寻找当前所在本机。
应用程序在设备中唯一的标识。
端口号:由两个字节表示的整数,取值范围:0~65535
其中0~1023之间的端口号用于一些知名的网络服务或者应用。
我们自己使用1024以上的端口号就可以了。
注意:一个端口号只能被一个应用程序使用。
计算机网络中,连接和通信的规则被称为网络通信协议
OSI参考模型 | TCP/IP 参考模型 | TCP/IP 参考模型各层对应协议 | 面向哪些 |
---|---|---|---|
应用层 | 应用层 | HTTP\FTP\Telnet\DNS | |
表示层 | 应用层 | HTTP\FTP\Telnet\DNS | |
会话层 | 应用层 | HTTP\FTP\Telnet\DNS | |
传输层 | 传输层 | TCP\UDP… | 选择传输使用的TCP,UDP协议 |
网络层 | 网络层 | IP\ICMP\ARP | 封装IP |
数据链路层 | 物理+数据链路层 | 硬件设备 010101010101… | 转换成二进制利用物理设备传输 |
物理层 | 物理+数据链路层 | 硬件设备 010101010101… | 转换成二进制利用物理设备传输 |
UDP协议
用户数据报协议(User Datagram Protocol)
UDP是面向无连接通信协议。
速度快,有大小限制一次最多发送64K,数据不安全,易丢失数据
TCP协议
传输控制协议TCP(Transmission Control Protocol)
TCP协议是面向连接的通信协议。
速度慢,没有大小限制,数据安全。
public class SendMessageDemo { //发送数据通过Socket发送 public static void main(String[] args) throws IOException { // 1. 创建Socket DatagramSocket datagramSocket = new DatagramSocket(); byte buf[] = "Hello Word".getBytes(StandardCharsets.UTF_8); int offset = buf.length; InetAddress address = InetAddress.getByName("127.0.0.1"); int port = 10086; // 打包数据,此处需要明确address, port这样创建的DatagramPacket才可以被发送 // 否则会提示 null address || null buffer // 该构造函数有英文 Constructs a datagram packet for sending packets DatagramPacket p = new DatagramPacket(buf, offset, address, port); // 发送打包的内容并关闭Socket datagramSocket.send(p); datagramSocket.close(); } }
public class ReceiveMessageDemo {
public static void main(String[] args) throws IOException {
DatagramSocket datagramSocket = new DatagramSocket(PORT);
byte[] buf = new byte[1024];
DatagramPacket p = new DatagramPacket(buf, buf.length);
// 该方法是阻塞的
datagramSocket.receive(p);
System.out.println(new String(p.getData(), 0, p.getLength()));
datagramSocket.close();
}
}
发送与接收都使用到了DatagramSocket、DatagramPacket,DatagramPacket不指定端口号则代表为接收方,
DatagramSocket 的receive方法也代表了此文接收方。
单播
以前的代码就是单播
组播
组播地址:
224.0.0.0 ~ 239 - 255.255.255
(其中 224.0.0.0 ~ 224.0.0.255 为预留的组播地址)
广播
广播地址:255.255.255.255
TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象
通信之前要保证连接已经建立
通过Socket产生IO流来进行网络通信
import java.io.IOException; import java.net.DatagramPacket; import java.net.InetAddress; import java.net.MulticastSocket; import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; import java.util.Scanner; public class ChatRoom { public static void main(String[] args) throws IOException { System.out.println("Please enter your username:"); Scanner scanner = new Scanner(System.in); String username = scanner.nextLine(); User user = new User(username); user.start(); } } class User { private InetAddress group; private int port; private String username; public User(String username) throws UnknownHostException { this.group = InetAddress.getByName("224.0.0.1"); this.port = 8888; this.username = username; } public void start() throws IOException { MulticastSocket multicastSocket = new MulticastSocket(this.port); multicastSocket.joinGroup(this.group); new Thread(new RunnableTask(multicastSocket, this.username)).start(); System.out.println("Begin Chat..."); Scanner scanner = new Scanner(System.in); while (true) { String messages = scanner.nextLine(); messages = this.username + ":" + messages; byte[] buf = messages.getBytes(StandardCharsets.UTF_8); DatagramPacket packet = new DatagramPacket(buf, buf.length, group, this.port); multicastSocket.send(packet); } } } class RunnableTask implements Runnable { private MulticastSocket multicastSocket; private String username; public RunnableTask(MulticastSocket multicastSocket, String username) { this.multicastSocket = multicastSocket; this.username = username; } @Override public void run() { byte[] bytes = new byte[1024]; while (true) { try { DatagramPacket packet = new DatagramPacket(bytes, 0, bytes.length); multicastSocket.receive(packet); String userNameAndMessage = new String(packet.getData(), 0, packet.getLength()); if (userNameAndMessage.contains(this.username)) { continue; } System.out.println(userNameAndMessage); } catch (IOException e) { e.printStackTrace(); } } } }
注意点:客户端/服务端 发送完数据需要通过socket关闭OutPut,为了增加读写效率使用了Buffered流
客户端
import java.io.*; import java.net.Socket; public class Client { public static void main(String[] args) throws IOException { Socket socket = new Socket("127.0.0.1", 10000); File file = new File("D:\\Program Files\\IdeaProjects\\mysocketnet\\clientdir\\1.png"); FileInputStream fileInputStream = new FileInputStream(file); BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream); OutputStream outputStream = socket.getOutputStream(); BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream); // 数据缓冲区 byte[] bytes = new byte[1024]; int len; while ((len = bufferedInputStream.read(bytes)) != -1) { // 缓冲区最后一次的长度可能不是1024,需要通过InputStream.read 确定 bufferedOutputStream.write(bytes, 0, len); } socket.shutdownOutput(); InputStream inputStream = socket.getInputStream(); InputStreamReader inputStreamReader = new InputStreamReader(inputStream); BufferedReader bufferedReader = new BufferedReader(inputStreamReader); System.out.println(bufferedReader.readLine()); socket.close(); } }
服务端
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class Server { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(10000); ExecutorService executorService = Executors.newCachedThreadPool(); while (true) { Socket socket = serverSocket.accept(); executorService.submit(new MyRunnable(socket)); } // serverSocket.close(); } }
自定义任务
import java.io.*; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.UUID; public class MyRunnable implements Runnable { Socket socket; public MyRunnable(Socket socket) { this.socket = socket; } @Override public void run() { InputStream inputStream = null; try { inputStream = this.socket.getInputStream(); } catch (IOException e) { e.printStackTrace(); } String replace = UUID.randomUUID().toString().replace("-", ""); FileOutputStream fileOutputStream = null; try { fileOutputStream = new FileOutputStream("D:\\Program Files\\IdeaProjects\\mysocketnet\\serverdir\\" + replace + ".png"); } catch (FileNotFoundException e) { e.printStackTrace(); } byte[] bytes = new byte[1024]; int read = 0; // inputStream.read 会一致读取,直到socket发送了shutdownOutput while (true) { try { if ((read = inputStream.read(bytes)) != -1) { break; } } catch (IOException e) { e.printStackTrace(); } try { fileOutputStream.write(bytes, 0, read); } catch (IOException e) { e.printStackTrace(); } } OutputStream outputStream = null; try { outputStream = socket.getOutputStream(); } catch (IOException e) { e.printStackTrace(); } String message = "数据接受完毕"; try { outputStream.write(message.getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { e.printStackTrace(); } try { socket.shutdownOutput(); } catch (IOException e) { e.printStackTrace(); } try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。