网络编程(Socket)

网络编程三要素

  • IP地址:网络中某一台设备的唯一标识
ip地址分为:ipv4和ivp6
 ivp4:48个二进制数表示 如
 192.168.0.1
 ivp6:816个二进制数表示 如:
 2001.0db8.3c4d.0015.0000.0000.12af.1a2b
  • 端口号:设备中应用程序的标识
端口号的范围: 0~65535
常用端口号: 8080(tomcat服务器的端口号)80(网络通信的默认端口号)3306(Mysql数据库的端口号)
注意:操作系统中已经使用了一些端口号(0~1024)被使用,我们尽量选择1024之后的端口号
  • 协议:网络通信的规则
UDP:面向无连接不可靠的网络协议(不靠谱,效率高) 音频 视频传输
Tcp:面向有连接的可靠的网络协议(靠谱、效率低)文件上传、文件下载

UDP通信

在这里插入图片描述
发送端

1.创建DatagramSocket对象(邮局)
2.创建数据包DatagramPacket对象(打包裹)
3.发送数据包send方法
4.释放资源close
//1.创建DatagramSocket对象(邮局)
DatagramSocket ds=new DatagramSocket();

//2.创建数据包DatagramPacket对象(打包裹)
byte[] bs="helloworld".getBytes();
String ip="127.0.0.1"; //127.0.0.1是一个本机的地址,发送的目的地为本机
int port=10086;
DatagramPacket dp=new DatagramPacket(bs,bs.length,InetAddress.getByName(ip),port);

//3.发送数据包send方法
ds.send(dp);

//3.发送数据包send方法
ds.send(dp);

接收端

1.创建DatagramSocket对象邮局(邮局) 指定端口号
2.创建数据包DatagramPacket对象(空包裹)
3.发送数据包receive方法
4.解析数据包(拆包裹)
5.释放资源close
 //1.创建DatagramSocket对象 指定端口号
DatagramSocket ds=new DatagramSocket(10086);

//2.接受数据包
byte[] bs=new byte[1024];
DatagramPacket dp=new DatagramPacket(bs,bs.length);
ds.receive(dp);  //阻塞

//3.拆包
//获取包中的数据
byte[] data = dp.getData();
//获取数据的有效长度
int length = dp.getLength();
//把字节数组转换为字符串
String str=new String(data,0,length);
System.out.println(str);

//4.释放资源
ds.close();

TCP通信

想要完成TCP通信就需要有客服端程序和服务端程序。
在这里插入图片描述
TCP客服端

public class Client {
    public static void main(String[] args) throws IOException {
        //创建Socket对象,绑定服务端的ip地址 和 端口号
        //如果服务端存在,则就可以建立连接
        Socket socket=new Socket("127.0.0.1",10010);

//获取输出流对象,输出目的网络
        OutputStream out = socket.getOutputStream(); 
        out.write("hello".getBytes());

//获取输入流,读取服务端回写的数据
        InputStream in = socket.getInputStream();
        byte[] bs=new byte[1024];
        int len=in.read(bs);
        //把读取到的有效字节个数转换为字符串
        String str=new String(bs,0,len);
        System.out.println("服务端返回数据:"+str);
//释放资源
        socket.close();
    }
}

TCP服务端

public class Server {
    public static void main(String[] args) throws IOException {
        //创建ServerSocket对象,绑定程序的端口号10010
        ServerSocket ss=new ServerSocket(10010);
        //监听客户端
        Socket s = ss.accept(); //阻塞,等待客户端过来连接

//获取输入流对象
        InputStream in = s.getInputStream();
        byte[] bs=new byte[1024];
        int len = in.read(bs);
        //把读取到的有效字节个数转换为字符串
        String str=new String(bs,0,len);
        System.out.println("客户端发过来的数据:"+str);

 //获取输出流对象,往客户端回写数据
        OutputStream out = s.getOutputStream();
        out.write("你好".getBytes());

//释放资源
        s.close();
    }
}

文件上传

在这里插入图片描述
客户端

public class Client {
    public static void main(String[] args) throws IOException {
        //创建Socket对象,绑定服务端的ip地址 和 端口号
        //如果服务端存在,则就可以建立连接
        Socket socket=new Socket("127.0.0.1",10010);
        //获取输出流对象,输出目的网络
        OutputStream out = socket.getOutputStream();

        //把一个a.txt文件中的数据发送到服务端
        File file = new File("day12-code/itheima20.jpg");
        FileInputStream fis=new FileInputStream(file);

        //一边读一边写
        byte[] bytes=new byte[1024];
        int len;
        while ((len=fis.read(bytes))!=-1){
            out.write(bytes,0,len);
        }
        //写结束标记,告诉服务端我的数据写完了
        socket.shutdownOutput();
        fis.close();

        //获取输入流,读取服务端回写的数据
        InputStream in = socket.getInputStream();
        byte[] bs=new byte[1024];
        len=in.read(bs);
        //把读取到的有效字节个数转换为字符串
        String result=new String(bs,0,len);
        System.out.println("服务端返回数据:"+result);

        //释放资源
        socket.close();
    }
}

服务端

public class Server {
    public static void main(String[] args) throws IOException {
      //创建ServerSocket对象,绑定程序的端口号10010
      ServerSocket ss=new ServerSocket(10010);

      //监听客户端
      Socket s = ss.accept(); //阻塞,等待客户端过来连接
      //获取输入流对象
      InputStream in = s.getInputStream();
      //写入文件的流,用来把读取到的数据保存到文件中
      //生成一个文件
      long time = System.currentTimeMillis();
      String filename="itheima"+time+".jpg";

      //用于往服务端的文件中写如数据
      FileOutputStream fos=new FileOutputStream("/Users/wangqi/Desktop/upload/"+filename);

      //读取客户端发过来的数据
      byte[] bs=new byte[1024];
      //先读取一次,获取文件名称
      int len;
      while ((len=in.read(bs))!=-1){
        //String str = new String(bs, 0, len);
        //把读取到的数据,往服务端的文件中写
        fos.write(bs,0,len);
      }

      //获取输出流对象,往客户端回写数据
      OutputStream out = s.getOutputStream();
      out.write("上传成功".getBytes());
        
      //释放资源
      s.close();
    }
}

文件上传(多线程)

客户端

public class Client {
    public static void main(String[] args) throws IOException {
        //创建Socket对象,绑定服务端的ip地址 和 端口号
        //如果服务端存在,则就可以建立连接
        Socket socket=new Socket("127.0.0.1",10086);
        //获取输出流对象,输出目的网络
        OutputStream out = socket.getOutputStream();

        //把一个a.txt文件中的数据发送到服务端
        File file = new File("day12-code/itheima15.jpg");
        FileInputStream fis=new FileInputStream(file);

        //一边读一边写
        byte[] bytes=new byte[1024];
        int len;
        while ((len=fis.read(bytes))!=-1){
            out.write(bytes,0,len);
        }
        //写结束标记,告诉服务端我的数据写完了
        socket.shutdownOutput();
        fis.close();

        //获取输入流,读取服务端回写的数据
        InputStream in = socket.getInputStream();
        byte[] bs=new byte[1024];
        len=in.read(bs);
        //把读取到的有效字节个数转换为字符串
        String result=new String(bs,0,len);
        System.out.println("服务端返回数据:"+result);

        //释放资源
        //socket.close();
    }
}

服务端
服务端可以为多个Socket提供上传文件服务,当监听到一个Socket连接过来就为其开一条线程,执行上传文件的代码

  • 上传文件任务(UploadRunnable)
public class UploadRunnable implements Runnable {
    private Socket s;
    public UploadRunnable(Socket s) {
        this.s = s;
    }
    @Override
    public void run() {
        FileOutputStream fos=null;
        try {
            //获取输入流对象
            InputStream in = s.getInputStream();
            //写入文件的流,用来把读取到的数据保存到文件中
            //生成一个文件
            long time = System.currentTimeMillis();
            String filename="itheima"+time+".jpg";

            fos=new FileOutputStream("/Users/wangqi/Desktop/upload/"+filename);

            //读取客户端发过来的数据
            byte[] bs=new byte[1024];
            //先读取一次,获取文件名称
            int len;
            while ((len=in.read(bs))!=-1){
                //String str = new String(bs, 0, len);
                fos.write(bs,0,len);
            }

            //获取输出流对象,往客户端回写数据
            OutputStream out = s.getOutputStream();
            out.write("上传成功".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(fos!=null){
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 服务端主程序
public class Server {
    public static void main(String[] args) throws IOException {
        //创建ServerSocket对象,绑定程序的端口号10010
        ServerSocket ss=new ServerSocket(10086);

        while (true){
            //监听客户端
            Socket s = ss.accept(); //阻塞,等待客户端过来连接
            //开启一个线程,专门为这个客户端提供服务
            UploadRunnable ur = new UploadRunnable(s);
            Thread t=new Thread(ur);
            t.start();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值