Java基础23 网络编程 socket套接字流 TCP传输总结

一、网络编程的概念

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的通信

  1. 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);
            }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值