java基础day23

Day23
一、网络编程

1、计算机网络:是不同地方借助网络来进行数据传输和交互的媒介
2、网络编程的三大要素:IP、端口号、协议
3、InetAddress(java提供获取IP的类)

  • public static InetAddress getLocalHost():返回本地主机;
  • public String getHostAddress():获取ip地址;
  • public String getHostName():获取ip的主机名;

4、端口号:当软件开启后,系统默认生成一个最大长度为两个字节的十进制,也可以自己设置

常用软件的端口号:  
  • Tomcat:8080
  • oracle:1521
  • mysql:3306
  • qq:4000
  • 网易邮箱的端口号:137
二、协议(主要是传输层:TCP、UDP+xmpp协议==>即时通讯qq、微信)

1、UDP面向无连接的协议:传输的数据快,但是可能会丢数据,出现卡顿
2、TCP面向连接的协议:传输慢,不会丢失数据(创建连接需要三次握手)《QQ》
3、HTTP、HTTPS都是属于一次性的连接,也就是客户端与服务器交互完后,请求就会断开《HTTPS=HTTP+ssl证书,保证了数据传输的安全性,大部分网站都是使用这个协议》

三、面向TCP协议进行通信

1、Socket类提供建立连接套接字的方式,即两个机器间通信的端点
2、构造方法:public Socket(String host,int port):传递两个参数,一个ip地址,一个是端口号(如果是本机ip地址传递localhost)
3、常规的方法:

  • public OutputStream getOutputStream()throws IOException:写数据的流对象;
  • public InputStream getInputStream()throws IOException:读取数据的流对象;
  • public void shutdownOutput()throws IOException:关闭对应端口的输出流(单方面);
  • public void shutdownInput()throws IOException:关闭对应端口的输入流(单方面);
注意:  
  • 在客户端或服务端通过socket.shutdownOutput()都是单向关闭的,即关闭客户端的输出流并不会关闭服务端的输出流,所以是一种单方向的关闭流
  • 通过socket.shutdownOutput()关闭输出流,但socket仍然是连接状态,连接并未关闭
  • 如果直接关闭输入或输出流,即in.close()或out.close(),会直接关闭socket
  • 服务器(ServerSocket实现服务器套接字)
package com.yxlim.day23;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * 先启动服务端,再启动客户端
 */
public class TCPServer {
    public static void main(String[] args) {
        try {
            //创建服务器端口
            ServerSocket server = new ServerSocket(6666);
            //阻塞式接收连接,连接成功返回socket对象
            Socket socket = server.accept();
            //获取连接传输的输入流
            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String s = null;
            while ((s = br.readLine()) != null) {  //读取数据
                System.out.println(s);
            }
            socket.shutdownInput();//(单方面)关闭服务器输入流
            //回应
            OutputStream os=socket.getOutputStream();
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
            bw.write("Hi");
            bw.flush();
            socket.shutdownOutput();//(单方面)关闭服务器输出流
            bw.close();//关闭流
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

  • 客户端
package com.yxlim.day23;

import java.io.*;
import java.net.Socket;

/**
 * 先启动服务端,再启动客户端
 */
public class TCPClient {
    public static void main(String[] args) {
        try {
            //建立客户端端口
            Socket socket=new Socket("localhost",6666);
            OutputStream os=socket.getOutputStream();
            BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os));
            bw.write("Hello");
            bw.flush();
            socket.shutdownOutput();
            //接收回应
            InputStream is=socket.getInputStream();
            BufferedReader br=new BufferedReader(new InputStreamReader(is));
            String s=null;
            while ((s=br.readLine())!=null){
                System.out.println(s);
            }
            socket.shutdownInput();
            br.close();
            bw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

  • 多线程服务器(接收多个客户端的连接)
package com.yxlim.day23.ThreadServer;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
/**
 * 多线程服务器(客户端不变)
 */
public class TCPServer extends Thread{
    private Socket socket;
    //利用构造器传入端口
    public TCPServer(Socket socket){
        this.socket=socket;
    }
    @Override
    public void run() {
        try {
            //获取端口输入流
            InputStream is = socket.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String s = null;
            while ((s = br.readLine()) != null) {
                System.out.println(s);  //打印传输的数据
            }
            socket.shutdownInput();//关闭端口输入流
            //回应
            OutputStream os=socket.getOutputStream();//获取端口的输出流
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
            bw.write("Hi");//输出数据
            bw.flush();
            socket.shutdownOutput();  //关闭端口输出流
            bw.close();
            br.close();//关闭流,也会关闭连接
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        try {
            //建立服务器端口
            ServerSocket server= new ServerSocket(7777);
            while (true) { //当有客户端访问,利用线程建立一条连接
                Socket socket=server.accept();
                new TCPServer(socket).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4、使用socket实现文件的上传的功能(客户端上传文件、服务器下载到服务器的存储),客户端+服务器+IO流文件读取写入操作

四、面向UDP协议进行通信

1、传输类主要是DatagramSocket(表示建立用来发送和接收数据报的套接字)、DatagramPacket(表示将数据报打包传输)
2、DatagramSocket构造方法:

  • public DatagramSocket(int port,InetAddress laddr):第一个数端口号,第二个参数是地址;
  • public DatagramSocket(int port):参数是端口号

(1)常规方法:

  • public void send(DatagramPacket p)throws IOException:发送数据包;
  • public void receive(DatagramPacket p)throws IOException:接收数据包;

3、DatagramPacket构造方法:

  • DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port);
  • DatagramPacket(byte[] buf, int offset, int length, SocketAddress address);

(1)常规方法:

  • public SocketAddress getSocketAddress():返回的就是SocketAddress;
  • public byte[] getData():获取缓冲区的数据;

4、实现Runnable接口实现多线程UDP通信

package com.yxlim.day23.UDP;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
 * 服务器
 */
public class Server implements Runnable{
    private DatagramSocket server;//创建服务器套接字
    private String name;//对话人姓名
    public Server(int port,String name){
        this.name=name;
        try {
            server=new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void run() {
        while (true){
            try {
                byte[] container = new byte[1024 * 60];//创建容器
                //包装容器
                DatagramPacket dp = new DatagramPacket(container, 0, container.length);
                server.receive(dp);//阻塞式接收数据包
                byte[] datas = dp.getData();//将数据包转成字节数组
                int len = dp.getLength();
                String s=new String(datas, 0, len);//将字节数组转成字符串
                System.out.println(name+":"+s);
                if("再见".equals(s)){//退出(需要通信双方都退出才算退出)
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        server.close();//关闭服务器
    }
}

package com.yxlim.day23.UDP;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
/**
 * 客户端
 */
public class Client implements Runnable{
    private DatagramSocket client;//创建客户端套接字
    private BufferedReader reader;//创建键盘输入
    private String toIP;//服务器IP
    private int toPort;//服务器端口
    public Client(int port,String toIP,int toPort){
        this.toIP=toIP;
        this.toPort=toPort;
        try {
            client=new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
        reader=new BufferedReader(new InputStreamReader(System.in));
    }
    @Override
    public void run() {
        while (true){
            try {
                String s=reader.readLine();//键盘输入字符串
                byte[] datas=s.getBytes();
                //打包成数据包
                DatagramPacket packet=new DatagramPacket(datas,0,datas.length,
                        new InetSocketAddress(toIP,toPort));
                client.send(packet);//发送数据包
                if("再见".equals(s)){//退出(需要通信双方都退出才算退出)
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        client.close();//关闭客户端
    }
}

public class TalkOne {
    public static void main(String[] args) {
        new Thread(new Server(5555,"xiao李")).start();//接收
        new Thread(new Client(6666,"localhost",7777)).start();//发送
    }
}
public class TalkTwo {
    public static void main(String[] args) {
        new Thread(new Client(8888,"localhost",5555)).start();//发送
        new Thread(new Server(7777,"xiao范")).start();//接收
    }
}
  • 基于UDP比较繁琐,且没有获取流对象的方法,开发中多用第三方jar包
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值