文章目录
前言
Java中的网络编程已经是属于JavaSE部分的尾声内容了,这一周剩下的还有一个反射的内容。都属于理论性与操作性较强的部分,如果内容错误欢迎留言指点
以下是本篇文章正文内容,下面案例可供参考
一、什么是网络编程
(1)计算机网络
内容:所谓计算机网络,是指将空间上具有独立功能的多台计算机以及它的外部设备(例如路由器等),通过通信线路连接起来,在网络操作系统,网络管理软件以及网络通信协议的管理下,实现资源共享和信息传递的计算机系统。
(2)网络编程
实现多态计算机之间数据共享与传递,网络应用程序主要组成是:网络编程+IO流+多线程
(3) 网络三要素与三大协议
3.1网络三要素
网络通讯模型:请求(客户端)—》响应请求(服务端) 内容:网络三大要素为:IP地址 、 端口号(port)、 网络协议(数据传输的规则) IP地址:网络中计算机的唯一标识(IP地址是一个32位的二进制数据,为了方便,将一个字节的二进制转换为一个十进制的数据),IP地址的组成=网络号段+主机段(IPV4是32位,IPV6是128位,我们的计算机通常是IPV4,本机的IP地址都是“127.0.0.1”); 端口号:每一个网络程序都至少一个端口号,这是用于标示进程的逻辑地址,不同的地址其端口号标示不同,有效端口号范围:0 ~ 65535,其中0 ~ 1024是系统使用或保留端口 网络协议:都是数据传输的规则,TCP 、UDP都是传输层的协议(后面会详细介绍)
3.2网络三大协议
TCP: UDP: Http:
(3)套接字“Socket”的使用
套接字的内容:如果要具体讲的话他就有点烧脑了,我们就简单提一下它的功能,Socket是将网络三大要素中的 IP 和 端口号 打包成了一个内容使得计算机之间的交流更加简单便利,Scoket也叫套接字,其表示的是IP地址和端口号的组合。网络编程主要就是指Socket编程,网络间的通信其实就是Socket间的通信,数据就通过IO流在两个Scoket间进行传递。
二、三大协议的使用步骤与操作案例
(1)TCP协议(面向连接的协议,可靠性更高)
内容:三次握手,四次挥手类似于打电话 理解图如下:
(2)UDP协议(无连接的协议)
内容:单方面发送消息数据包,类似于发快递。 特点:容易造成数据丢失,故此常应用于视频聊天,相比较于TCP它更显得不负责任,此外UDP没有服务端,只有客户端即直接行驶的是用户之间的交流没有服务端的介入。
(3)TCP VS UDP
(4)HTTP协议
三、实战案例:实现不同用户之间的聊天
(1)TCP案例部分:
1.1一对一聊天
说明:实现一对一聊天需要用到线程的知识,为了能够使得客户端与服务端之间的交流能够顺利创建一个接收的线程
客户端(Client)代码如下:
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws Exception {
Socket socket=new Socket("127.0.0.1",8080);
Scanner input=new Scanner(System.in);
new ReceiveThread(socket).start();
PrintStream ps=new PrintStream(socket.getOutputStream());
while (true){
ps.println("雍仲:"+input.next());
}
}
}
服务端(Server):
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket = new ServerSocket(8080);
Socket socket=serverSocket.accept();
Scanner input=new Scanner(System.in);
new ReceiveThread(socket).start();
PrintStream ps=new PrintStream(socket.getOutputStream());
while (true){
ps.println("中国人寿保险:"+input.next());
}
}
}
线程接受器
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class ReceiveThread extends Thread{
private Socket socket;
public ReceiveThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
BufferedReader bufferedReader=null;
try {
bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
while (true){
String readLine=null;
try {
readLine=bufferedReader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(readLine);
}
}
}
1.2实现文件的传输(不正经系列)
这个案例的要求的实现主要是依靠对输入流以及输出流的熟练使用,以及通过对网络编程Socket的熟练使用
Client客户端
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws Exception {
Socket socket=new Socket("127.0.0.1",8080);
FileInputStream fis=new FileInputStream("明日花绮罗.jpg");
OutputStream out=socket.getOutputStream();
int len;
byte [] bs=new byte[1024];
while ((len=fis.read(bs))!=-1){
out.write(bs,0,len);
}
fis.close();
out.close();
}
}
Server服务端类:
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws Exception {
ServerSocket serverSocket=new ServerSocket(8080);
Socket socket=serverSocket.accept();
InputStream is=socket.getInputStream();
OutputStream os=new FileOutputStream("download.jpg");
int len;
byte [] bs=new byte[1024];
while ((len=is.read(bs))!=-1){
os.write(bs,0,len);
}
os.close();
is.close();
}
}
结果展示:
1.3多人之间聊天
说明 :对于实现多人聊天,我们需要注意的一点就是在我们不知道到底有多少个用户在聊天的时候我们就无法确定有多少个客户端Socket,因此就不能在服务端中明确创建多少个服务端的Socket来进行对象之间的匹配,因此我们需要用到多线程,而谈及多线程的话明显是要实现多个用户的交流,而对于这一部分我们作为服务器的控制者,那么我们就需要收集到所有用户的IP地址和Socket来进行他们之间的消息收集和发送到其余的用户那儿去故此 我们需要用到一个Map,而这个Map就是多线程下的安全性最高的ConcurrenHashMap。
创建用户端类(Client)
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) throws Exception{
Socket socket=new Socket("127.0.0.1",8080);
Scanner input=new Scanner(System.in);
new ReceiveThread(socket).start();
PrintStream ps=new PrintStream(socket.getOutputStream());
while (true){
ps.println("雍仲杨:"+input.next());
}
}
}
创建服务端类(Server)
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ConcurrentHashMap;
public class Server {
public static ConcurrentHashMap<InetAddress,Socket> map=new ConcurrentHashMap<>();
public static void main(String[] args) throws Exception {
ServerSocket serverSocket=new ServerSocket(8080);
while (true){
Socket socket=serverSocket.accept();
InetAddress ip=socket.getInetAddress();
map.put(ip,socket);
new ServerThread(socket).start();
}
}
}
创建接受线程类(ReceiveThread)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
public class ReceiveThread extends Thread{
private Socket socket;
public ReceiveThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
BufferedReader br=null;
try {
br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
while (true){
String readLine=null;
try {
readLine=br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(readLine);
}
}
}
创建服务线程类(ServerThread)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
public class ServerThread extends Thread{
private Socket socket;
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
BufferedReader bufferedReader = null;
try {
bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
while (true){
String readLine=null;
try {
readLine =bufferedReader.readLine();
System.out.println(readLine);
ConcurrentHashMap<InetAddress,Socket> map=Server.map;
Set<Entry<InetAddress,Socket>> entrySet=map.entrySet();
for (Entry<InetAddress,Socket> entry:entrySet) {
InetAddress key=entry.getKey();
Socket value=entry.getValue();
if (socket.getInetAddress()!=key){
PrintStream ps=new PrintStream(value.getOutputStream());
ps.println(readLine);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
(2)UDP部分案例:
2.1通过用户之间的发送快递的形式来解释
创建第一个用户端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Client01 {
public static void main(String[] args) throws IOException {
DatagramSocket socket=new DatagramSocket();
byte [] bs="鲜花一束~~~".getBytes();
DatagramPacket packet=new DatagramPacket(bs,bs.length, InetAddress.getByName("127.0.0.1"),8080);
socket.send(packet);
byte [] buf=new byte[1024];
packet=new DatagramPacket(buf, buf.length);
socket.receive(packet);
System.out.println(new String(buf).trim());
}
}
创建用户端2
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
public class Client02 {
public static void main(String[] args) throws IOException {
DatagramSocket socket=new DatagramSocket();
byte [] bs=new byte[1024];
DatagramPacket packet=new DatagramPacket(bs,bs.length);
socket.receive(packet);
System.out.println(new String(bs).trim());
byte [] buf="典藏版黑金卡".getBytes();
packet=new DatagramPacket(buf, buf.length,packet.getSocketAddress());
socket.send(packet);
}
}
总结
本文主要是通过一些基本理论+实战场景来进行梳理的,内容还不完整,后期我会慢慢进行填补,若所写内容之中有错误请指正。
|