一、网络编程的概念
1.计算机网络:将不同地区的计算机,使用网络来进行连接 实现不同地区的数据的交互与共享(互联时代)
2. 网络编程的三要素:IP地址 端口号 协议
3. ip地址:是在网络连接中 每一台电脑的唯一标识
ip地址的分类 IP4 IP6
IP4 是由四个字节的二进制组成 由于不好记忆 IP4 改成以十进制 来进行表示 每一个字节是以.来进行分割
192.168.1.33 子网 10.1
IP6 ip6是由16进制来组成的
查看IP地址
第一步:windons+r
第二步:cmd
第三步 指定 ipconfig
查看服务器是否可以访问 ping 服务器的IP地址
ping + ip地址
InetAddress 此类表示互联网协议(IP)地址
常用的方法
package day23;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Test01 {
public static void main(String[] args) throws UnknownHostException {
InetAddress in = InetAddress.getByName("DESKTOP-FQLA3DE");
//获取ip地址 10.3.131.45
String ip= in.getHostAddress();
System.out.println(ip);
//获取主机
String host = in.getHostAddress();
System.out.println(host);
}
}
4.端口号:每一个进程的唯一的标识 每一个执行的程序的唯一的标识 这个标识可以自行设置 也可以
由系统进行分配
端口号的范围0-65535 必须设置在这个范围之内 0-1024 这个范围之内的端口号 不进行使用 一
般是系统使用
常见的口号
tomcat:8080
mysql 3306
orcale 1207
qq 4000
5..协议: 数据再进行交互的时候遵循的规范 必须按照这个规范来进行传输 客户端与服务才能进行有效
的交互
常见的协议
TCP 面向连接的协议 三次握手 之后 表示连接成功 特点: 传输数据稳定安全 效率低一点
UDP 面向无连接的协议 特点: 传输数据安全性低 效率高 丢失数据 丢包
HTTP 一次性的协议 表示客户端与服务器连接成功 交互完成之后 就断开的了 一般用于web端
明文进行传输 数据没有进行任何加密 上线的项目都不能直接使用http
协议进行数据交互
HTTPS= http+ssl证书 ssl 证书 保证对传输的数据进行加密 保证数据的安全性
6.三次握手
7.http 请求
二、基于TCP 进行Socket通信
1.Socket 此类实现客户端套接字(也可以就叫“套接字”)。套接字是两台机器间通信的端点 可以两台
设备进行通信
3.ServerSocket 此类实现服务器套接字。 服务器套接字等待请求网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果
三、基于TCP 进行Socket通信-简单文本传输
1.客户端
步骤
1实例化Socket对象
2.获取到输入流 与输出流
3.向服务器与写数据
4.接受服务发送的数据
5.关闭资源
2.服务器
步骤
1.实例化 ServerSockket对象
2.调用其监听的方法
3.获取到输入流与输出流
4.接受客户端发送的数据 读取
5.客户端发送数据
6.关闭资源
3.代码
写入完数据需要soc.shutdownOutput(); 刷新保存才能读取
关闭资源 soc server 最后关闭
package day23;
import java.io.*;
import java.net.Socket;
/**
* 客户端 先写后读
*/
public class ClientStr {
public static void main(String[] args) throws IOException {
//实例化 Socket对象
Socket soc = new Socket("localhost", 8888);
InputStream is = soc.getInputStream();
OutputStream os = soc.getOutputStream();
//向服务器写数据
os.write("11111,我还要全息之影".getBytes());
//刷新
soc.shutdownOutput();
//======================接受服务器数据
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
//关闭资源
br.close();
os.close();
is.close();
soc.close();
}
}
package day23;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务器端 先运行服务器端在运行客户端 先读后写
*/
public class ServerStr {
public static void main(String[] args) throws IOException {
//实例化ServerSocket对象
ServerSocket server = new ServerSocket(8888);
//开始监听客户单
Socket soc = server.accept();
//获取输入流与输出流
InputStream is =soc.getInputStream();
OutputStream os =soc.getOutputStream();
//读取客户端发送的数据
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line =null;
while ((line = br.readLine())!=null){
System.out.println(line);
}
//服务器向客户端写入数据
os.write("扣1送地狱火".getBytes());
//刷新
soc.shutdownOutput();
//关闭资源 soc server 最后关闭
os.close();
br.close();
is.close();
soc.close();
server.close();
}
}
四、基于TCP进行Socket通信-传输对象
实体对象
package day23;
import java.io.Serializable;
public class Actor implements Serializable{
private String name;
private int age;
public Actor(){
}
public Actor(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Actor{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
服务器的代码
package day23;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务器端
*/
public class ServerObject {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//实例化ServerSocket 对象
ServerSocket server = new ServerSocket(8887);
//开始监听
Socket soc = server.accept();
//获取输出流 输入流
InputStream is =soc.getInputStream();
OutputStream os =soc.getOutputStream();
//读客户端对象
ObjectInputStream ois= new ObjectInputStream(is);
//调用读取的方法
Actor act = (Actor) ois.readObject();
System.out.println(act);
//给客户端一个反馈 响应
os.write("我是服务器,收到客户端的请求".getBytes());
//刷新
soc.shutdownOutput();
//关闭资源
os.close();
ois.close();
is.close();
soc.close();
server.close();
}
}
客户端代码
package day23;
import java.io.*;
import java.net.Socket;
/**
* 客户端
*/
public class ClientObject {
public static void main(String[] args) throws IOException {
//实例化Socket
Socket soc = new Socket("localhost",8887);
//获取输入流 输出流
InputStream is = soc.getInputStream();
OutputStream os = soc.getOutputStream();
//实例化对象
Actor ac = new Actor("狂徒张三",18);
//向服务器写对象 序列化对象流
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(ac);
//刷新
soc.shutdownOutput();
//读服务器返回的数据
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line =null;
while ((line= br.readLine())!=null){
System.out.println(line);
}
//关闭资源
br.close();
oos.close();
os.close();
is.close();
soc.close();
}
}
五、基于TCP进行Socket通信-多线程处理方案
代码
客户端1
package day23;
import java.io.*;
import java.net.Socket;
/**
* 客户端 先写后读
*/
public class ClientStr {
public static void main(String[] args) throws IOException {
//实例化 Socket对象
Socket soc = new Socket("localhost", 8888);
InputStream is = soc.getInputStream();
OutputStream os = soc.getOutputStream();
//向服务器写数据
os.write("11111,我还要全息之影".getBytes());
//刷新
soc.shutdownOutput();
//======================接受服务器数据
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
//关闭资源
br.close();
os.close();
is.close();
soc.close();
}
}
客户端2
package day23;
import java.io.*;
import java.net.Socket;
public class ClientStr1 {
public static void main(String[] args) throws IOException {
Socket soc =new Socket("localhost",8888);
InputStream is = soc.getInputStream();
OutputStream os =soc.getOutputStream();
os.write("我是你义父".getBytes());
soc.shutdownOutput();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line= br.readLine())!=null){
System.out.println(line);
}
br.close();
os.close();
is.close();
soc.close();
}
}
线程类
package day23;
import java.io.*;
import java.net.Socket;
public class MyThread extends Thread{
private Socket soc;
public MyThread(Socket soc) {
this.soc = soc;
}
@Override
public void run() {
try {
InputStream is = soc.getInputStream();
OutputStream os = soc.getOutputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line= br.readLine())!=null){
System.out.println(line);
}
//服务器向客户端写入数据
os.write("我是主播,别杀我".getBytes());
os.write("\r\n".getBytes());
os.write("扣1送地狱火".getBytes());
soc.shutdownOutput();
os.close();
br.close();
is.close();
soc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器
package day23;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerStr1 {
public static void main(String[] args) throws IOException {
//实例化ServerSocket对象
ServerSocket server = new ServerSocket(8888);
//死循环
while (true){
Socket soc =server.accept();
//实例化线程对象
MyThread th1=new MyThread(soc);
//开启线程
th1.start();
}
}
}
六、基于TCP进行Socket通信 文件上传
代码
客户端
package day23;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ClientFile {
public static void main(String[] args) throws IOException {
//实例化Socket对象
Socket soc = new Socket("localhost",8887);
//获取输入流 输出流
InputStream is = soc.getInputStream();
OutputStream os = soc.getOutputStream();
FileInputStream fis = new FileInputStream("E:\\admin01\\b\\c.txt\\gm01.jpg");
//读取本地文件
byte [] b =new byte[1024];
int leng =-1;
while ((leng=fis.read(b))!=-1){
//写入到服务器
os.write(b,0,leng);
}
//刷新
os.flush();
soc.shutdownOutput();
//关闭资源
os.close();
fis.close();
is.close();
soc.close();
}
}
服务器
package day23;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerFile{
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8887);
//进行监听
Socket soc = server.accept();
//得到输入流 输出流
InputStream is =soc.getInputStream();
//OutputStream os = soc.getOutputStream();
//将所有的图片保存在指定的文件夹下
File f = new File("E:\\admin");
//判断文件是否存在 不存在 创建
if(!f.exists()){
f.mkdirs();
}
//读取客户端发送的文件
byte [] b = new byte[1024];
int leng =-1;
//根据系统时间 将文件的名称随机生产
String fileName = System.currentTimeMillis()+".jpg";
FileOutputStream fos = new FileOutputStream(new File(f,fileName));
while ((leng=is.read(b))!=-1){
//写入
fos.write(b,0,leng);
}
fos.flush();
fos.close();
is.close();
soc.close();
server.close();
}
}
七、基于UDP的通信
- DatagramSocket 此类表示用来发送和接收数据报包的套接字。
将 DatagramSocket 绑定到一个更加具体的地址时广播包也可以被接收
2.构造方法
1.DatagramPacket 此类表示数据报包
客户端
1.实例化这个对象 DatagramSocket
2.构建一个包裹对象 DatagramPacket 并打包数据
3.发送包裹
服务器
1.实例化这个对象 DatagramSocket
2.构建一个包裹对象 用于接受客户端发送的信息
3.接受包裹 并拆包转为字符串
代码
客户端
package day23;
import java.io.IOException;
import java.io.StringReader;
import java.net.*;
public class Client {
public static void main(String[] args) throws IOException {
//实例化这个对象 DatagramSocket
DatagramSocket socket = new DatagramSocket();
//构建一个包裹对象 DatagramPacket
String str = "我是客户端的包裹";
//转换为字节
byte [] b1= str.getBytes();
InetAddress address = InetAddress.getByName("localhost");
DatagramPacket dp = new DatagramPacket(b1,0,b1.length
,address,8887);
//发送包裹
socket.send(dp);
//=========客户端接受包裹
byte [] b2 = new byte[1024];
DatagramPacket dp1 = new DatagramPacket(b2,b2.length);
socket.receive(dp1);
//需要进行拆包
System.out.println(new String(dp1.getData(),0,dp1.getData().length));
}
}
服务器代码
package day23;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
public class Server {
public static void main(String[] args) throws IOException {
//实例化 DatagramSocket 这个对象
DatagramSocket socket = new DatagramSocket(8887);
byte [] b =new byte[1024];
DatagramPacket dp = new DatagramPacket(b,b.length);
//调用接受包裹的方法
socket.receive(dp);
//拆包
System.out.println(new String(dp.getData(),0,dp.getData().length));
//================服务器向客户端发送包裹
String s1 = "收到包裹,恶狗请回答";
//构造一个包裹对象
DatagramPacket dp1 = new DatagramPacket(s1.getBytes(),0,
s1.getBytes().length,dp.getSocketAddress());
socket.send(dp1);
}
}
八、工厂设置模式
Pet pet = null;
if(){
pet = new Cat()
}
Inner in =null;
if(){
in = new Cat()
}
无论继承还是接口,先定义以一个父类为null,然后根据条件,字符串比较,使用自动向上转型 实例化父类或接口
第一种方式继承
父类
public abstract class Pet {
public abstract void eat();
}
狗类
public class Dog extends Pet {
@Override
public void eat() {
System.out.println("吃狗粮");
}
}
猫类
public class Cat extends Pet {
@Override
public void eat() {
System.out.println("吃猫粮");
}
}
企鹅类
public class Penguin extends Pet {
@Override
public void eat() {
System.out.println("吃鱼");
}
}
工厂类
/**
* 工厂类 就是为实例化对象
*/
public class Factory {
//定义一个静态方法来实例化对象
public static Pet getPet(String type){
Pet pet = null;
if (type.equals("dog")){
pet = new Dog();
}else if(type.equals("cat")){
pet = new Cat();
}else if(type.equals("penguin")){
pet = new Penguin();
}
return pet;
}
}
测试类
public class Test {
public static void main(String[] args) {
Pet p = Factory.getPet("dog");
p.eat();
}
}
第二种方式接口
接口
public interface Inner {
void eat();
}
狗类
public class Dog implements Inner {
@Override
public void eat() {
System.out.println("吃狗粮");
}
}
猫类
public class Cat implements Inner {
@Override
public void eat() {
System.out.println("吃猫粮");
}
}
工厂类
public class Factroy {
//提供一个静态的方法来实例化对象
public static Inner getInner(String type){
Inner in = null;
if(type.equals("dog")){
in = new Dog();
}else if(type.equals("cat")){
in= new Cat();
}
return in;
}
}
测试类
public class Test {
public static void main(String[] args) {
Inner in = Factroy.getInner("dog");
in.eat();
}
}
TCP传输总结
可以看作有一个套接字Socket 输入输出流 属于字节流
客户端 Socket soc = new Socket("localhost",8888);
其中localhost是代指本地服务器的ip地址,如果需要传到其他服务器,就改成其他服务器的ip地址 8888 是服务器的端口号
套接字的输入输出流 用于在服务器与客互端的两端的传输,无论是客户端还是服务器端与本地磁盘交互都需要传统字节流,文件输入输出流,对象输入输出流,字节流
InputStream is = soc.getInputStream();
OutputStream os = soc.getOutputStream();
需要用到读取写入的时候都写,只需要一个的时候只写一个
与本地磁盘交互
FileInputStream fis = new FileInputStream("E:\\admin01\\b\\otm01.jpg");
读取本地文件用传统字节流 fis.read(b),传到服务器端用套接字字节流os.write(b,0,leng);
byte [] b = new byte[1024];
int leng =-1;
while ((leng=fis.read(b))!=-1){
os.write(b,0,leng);
}
服务器端
ServerSocket server = new ServerSocket(8888);
Socket soc = server.accept();
生成一个服务器端的套接字 new ServerSocket(8888); 要和客户端的端口号对上才能接受到客户端的数据
得到套接字输入流输出流
InputStream is =soc.getInputStream();
//OutputStream os = soc.getOutputStream();
需要用到读取写入的时候都写,只需要一个的时候只写一个
与本地磁盘交互 创建文件 用传统字节流
//创建String文件名 以及File地址
String fileName = System.currentTimeMillis()+".jpg";
File f = new File("E:\\admin",fileName);
if(!f.exists()){
f.createNewFile();
}
//写入到本地 需要输出流
FileOutputStream fos = new FileOutputStream(f);
读取客户端的数据用套接字字节流is.read(b) 写入到本地用传统字节流fos.write(b,0,leng);
byte [] b =new byte[1024];
int leng=-1;
while ((leng=is.read(b))!=-1){
fos.write(b,0,leng);
}