网络编程概述: 什么是计算机网络 把不同区域的计算机(广义上的)通过通信设备和线路连接起来, 可以实现数据的传输和共享的系统. 实现不同计算机之间的联系,必须有介质连接. 最开始在一间办公室,后来一栋楼,一个城市,国家,全球 网络编程是干什么的 聊天--->聊天软件 QQ java语言支持网络间的数据传输,将底层的细节都封装起来, 给程序员提供了一套标准的类库,很方便使用java语言开发可以进行网络通信的软件 网络编程 借助计算机网络,实现我们所写的程序,在不同的电脑上,进行数据传输 网络编程核心问题: 如何找到网络世界中的目标主机,以及目标软件 win+r cmd ipconfig 查看自己电脑的ip 如何安全可靠的进行数据的传输 协议 规则 网络基本知识 网络模型 OSI参考模型,是一个理想化的标准模型 分成7层 实际上的使用Tcp/ip网络模型 分成4层 应用层(http) 运输层(协议) 网络层(IP) 物理链路层(硬件设备) 网络传输数据为何要分层 在不同的层中,对数据加入不同的头(协议 IP ) 逐层分工处理 通信要素: ip 端口 协议 目标主机,目标软件 IP:在网络世界中,是计算机的地址 局域网地址 连接到路由器,会自动分配IP 广域网地址 家里的宽带与外界连接 本机地址 本地回环地址 127.0.0.1 端口:计算机中运行中程序的编号,对应的是程序 IP找主机 端口找程序 ip+端口,找到目标计算机,以及你想要的程序 端口号0-65535 由于0-1024被一些系统程序使用, 所以我们开发的程序可以从1024-65535区间定义 但是不能与已有的端口冲突 如何安全传输---通信协议 为了安全可靠的进行数据传输,需要对传输的内容,速率,出错之后的处理办法等进行控制 而制定的一些规约,称为协议. 传输层有两个主要协议: TCP(传输控制协议TCP(Transmission Control Protocol)) 使用Tcp协议进行数据传输前,必须检测网络是否通畅, 客户端是否能连接到服务器端 如果能连接到,则进行数据传输,如果连接不到,会报错. 采用的是3次握手机制 tcp是可靠的,相对udp效率低 UDP(用户数据报协议UDP(User Datagram Protocol)) 将数据封装数据报 数据报包含 数据 自己的ip 目标ip 发送前不需要建立连接,直接发送,是否发送成功,不清楚
l
TCP
•
使用TCP协议前,须先建立TCP连接,形成传输数据通道
•
传输前,采用“
三次握手
”方式,是可靠的
•
TCP协议进行通信的两个应用进程:客户端、服务端
•
在连接中可进行大数据量的传输
•
传输完毕,需释放已建立的连接,效率低
•
在断开时要进行
“四次挥手
三次握手
![](https://i-blog.csdnimg.cn/blog_migrate/b8bbaf555a0bdcfddc80cb1164c7174b.png)
四次挥手
![](https://i-blog.csdnimg.cn/blog_migrate/81f9225b265afc0a7251a8281de822ff.png)
TCP编程
Socket常用方法
方法 | 功能 |
void close() throws IOException
|
关闭Socket,不可在以后的网络连接中使用,除非创建
新的套接字
|
InputStream getInputStream()
throws IOException
|
与Socket相关联的字节输入流,用于从Socket中读 数据。
|
OutputStream getOutputStream()
throws IOException
|
获取与Socket相关联的字节输出流,用于向Socket中写 数据
|
Sever Socket常用方法
方法 | 功能 |
Socket accept() throws IOException
| 等待客户端的连接请求,返回与该客户端进行通信用的Socket对象 |
void close()throws IOException | 关闭监听Socket |
客户端Socket的工作过程包含以下四个基本的步骤:
●
创建 Socket:
根据指定服务端的 IP 地址或端口号构造 Socket 类对象。若服务器端响应, 则建立客户端到服务器的通信线路。若连接失败,会出现异常。
●
打开连接到 Socket 的输入/出流:
使用 getInputStream()方法获得输入流, 使用 getOutputStream()方法获得输出流,进 行数据传输
●
按照一定的协议对 Socket 进行读/写操作:
通过输入流读取服务器放入线路的 信息(但不 能读取自己放入线路的信息),通过输出流将信息写入线程。
●
关闭 Socket:
断开客户端到服务器的连接,释放线路
服务器程序的工作过程包含以下四个基本的步骤:
●
调用 ServerSocket(int port) :创建一个服务器端套接字,并绑定到指定端 口上。用于监听 客户端的请求。
●
调用 accept():监听连接请求,如果客户端请求连接,则接受连接,返回通信 套接字对象。
●
调用 该Socket类对象的 getOutputStream() 和 getInputStream ():获取 输出流和输入流, 开始网络数据的发送和接收。
●
关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字。
基于TCP协议编程 服务器端: ServerSocket serverSocket=new ServerSocket(9999); Socket socket=serverSocket.accept();//监听 客户端: Socket socket=new Socket("127.0.0.1", 9999);//创建Socket对象时,建立与服务器端连接 socket.getInputStream();//获得输入流 socket.getOutputStream();//
package day15Intent.tcp.demo1;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) {
//创建客户端
try {
Socket socket=new Socket("127.0.0.1", 9999);
//在客户端向服务器端发送一句话
OutputStream outputStream=socket.getOutputStream();
String s="你好";
outputStream.write(s.getBytes());
} catch (IOException e) {
e.printStackTrace();
System.out.println("连接服务器失败");
}
}
}
package day15Intent.tcp.demo1;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) {
try {
//创建并启动服务器
ServerSocket serverSocket=new ServerSocket(9999);
while(true){
System.out.println("服务器启动成功");
Socket socket=serverSocket.accept();//监听有没有客户端连接到服务器,监听时,会阻断程序
System.out.println("有客户端连接到了服务器");
//接受客户端发送的数据
InputStream inputStream=socket.getInputStream();
byte[] bytes=new byte[100];
int size=inputStream.read(bytes);
String s=new String(bytes,0,size);
System.out.println(s);
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("服务器自动失败,端口被占用");
}
}
}
用户端与客户端循环输入接收
package day15Intent.tcp.demo2;
import com.sun.corba.se.impl.encoding.CDROutputStream;
import java.io.*;
import java.net.Socket;
import java.util.Scanner;
public class Client {
public static void main(String[] args) {
try {
Socket socket=new Socket("127.0.0.1",9999);
OutputStream outputStream=socket.getOutputStream();
while(true){
DataOutputStream dataOutputStream=new DataOutputStream(outputStream);
Scanner scanner=new Scanner(System.in);
System.out.println("客户端输入:");
String s=scanner.next();
dataOutputStream.writeUTF(s);
InputStream inputStream=socket.getInputStream();
DataInputStream dataInputStream=new DataInputStream(inputStream);
String s1=dataInputStream.readUTF();
System.out.println("客户端说:"+s1);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package day15Intent.tcp.demo2;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class Server {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(9999);
Socket socket = serverSocket.accept();
while(true){
InputStream inputStream = socket.getInputStream();
DataInputStream dataInputStream = new DataInputStream(inputStream);
String s = dataInputStream.readUTF();
System.out.println("客户端说:" + s);
//服务端向客户端回发消息
OutputStream outputStream = socket.getOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
Scanner scanner = new Scanner(System.in);
System.out.println("服务器端输入:");
String s1 = scanner.next();
dataOutputStream.writeUTF(s1);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
UDP编程
●
流 程:
1. DatagramSocket与DatagramPacket
2. 建立发送端,接收端
3. 建立数据报
4. 调用Socket的发送、接收方法
5. 关闭Socket
●
发送端与接收端是两个独立的运行程序
package day15Intent.udp;
import java.io.IOException;
import java.net.*;
//发送端
public class Send {
public static void main(String[] args) {
try {
DatagramSocket datagramSocket=new DatagramSocket();//负责发送数据报
byte[] bytes="你好".getBytes();//发送的数据
DatagramPacket datagramPacket=new DatagramPacket(bytes,0, bytes.length, InetAddress.getByName("127.0.0.1"),9999);
datagramSocket.send(datagramPacket);
datagramSocket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
package day15Intent.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
//接收端
public class Receive {
public static void main(String[] args) {
try {
DatagramSocket datagramSocket=new DatagramSocket(9999);
//封装一个数据报对象,用来接收数据
byte[] bytes=new byte[100];//用来封装数据
DatagramPacket datagramPacket=new DatagramPacket(bytes,0,bytes.length);
datagramSocket.receive(datagramPacket);//真正接受数据
//实际接收到的数组的长度
String s=new String(bytes,0,datagramPacket.getLength());
System.out.println(s);
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}