Java之socket网络编程

socket网络编程



一、网络编程概述


网络编程的目的

直接或间接地通过网络协议与其它计算机实现数据交换,进行通讯

网络编程中有两个主要的问题

①如何准确地定位网络上一台或多台主机;定位主机上的特定的应用

②找到主机后如何可靠高效地进行数据传输


二、网络通信要素概述

通信双方地址:

① IP
② 端口号


三、IP和端口号

IP 地址:InetAddress

本地回环地址(hostAddress):

127.0.0.1

主机名(hostName):

localhost

IP地址分类方式1:

IPV4 和 IPV6

IPV4:4个字节组成,4个0-255。大概42亿,30亿都在北美,亚洲4亿。2011年初已经用尽。以点分十进制表示,如192.168.0.1

IPV6:128位(16个字节),写成8个无符号整数,每个整数用四个十六进制位表示,数之间用冒号(:)分开,如3ffe:3201:1401:1280:c8ff:fe4d:db39:1984

IP地址分类方式2:

公网地址(万维网使用)和私有地址(局域网使用)

192.168.开头的就是私有址址,范围即为192.168.0.-192.168.255.255,专门为组织机构内部使用


Internet上的主机有两种方式表示地址:

域名(hostName):www.baiidu.com
IP 地址(hostAddress):183.232.231.172

域名解析:

域名容易记忆,当在连接网络时输入一个主机的域名后,域名服务器(DNS)负责将域名转化成IP地址,这样才能和主机建立连接

在这里插入图片描述


InetAddress类

方法声明功能描述
InetAddress getByName(String host)获取给定主机名的的IP地址,host参数表示指定主机
InetAddress getLocalHost()获取本地主机地址
String getHostName()获取本地IP地址的主机名
boolean isReachable(int timeout)判断在限定时间内指定的IP地址是否可以访问
String getHostAddress()获取字符串格式的原始IP地址
public class Test01 {
    public static void main(String[] args) throws UnknownHostException {
        // 获取给定主机名的的IP地址,host参数表示指定主机
        InetAddress inetAddress = InetAddress.getByName("192.168.0.106");
        // 获取获取本地IP地址的主机名
        String hostName = inetAddress.getHostName();
        // 获取IP地址
        String address = inetAddress.getHostAddress();
        System.out.println("hostName:" + hostName);
        System.out.println("address:" + address);
    }
}

四、网络协议


网络通信协议

计算机网络中实现通信必须有一些约定,即通信协议,对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准


通信协议分层的思想

在制定协议时,把复杂成份分解成一些简单的成份,再将它们复合起来。最常用的复合方式是层次方式,即同层间可以通信、上一层可以调用下一层,而与再下一层不发生关系


两个协议

① 传输控制协议TCP(Transmission Control Protocol)

② 用户数据报协议UDP(User Datagram Protocol)


TCP 和 UDP

TCP协议:

①使用TCP协议前,须先建立TCP连接,形成传输数据通道
②传输前,采用“三次握手”方式,点对点通信,是可靠的
③ TCP协议进行通信的两个应用进程:客户端、服务端
④在连接中可进行大数据量的传输
⑤传输完毕,需释放已建立的连接,效率低


UDP协议:

①将数据、源、目的封装成数据包,不需要建立连接
②每个数据报的大小限制在64K内
③发送不管对方是否准备好,接收方收到也不确认,故是不可靠的
④可以广播发送
⑤发送数据结束时无需释放资源,开销小,速度快


Socket

1、通信的两端都要有Socket,是两台机器间通信的端点

2、 网络通信其实就是Socket间的通信

3、Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输

4、一般主动发起通信的应用程序属客户端,等待通信请求的为服务端


Socket类的常用构造器

构造器说明
public Socket(InetAddress address,int port)创建一个流套接字并将其连接到指定 IP 地址的指定端口号
public Socket(String host,int port)创建一个流套接字并将其连接到指定主机上的指定端口号

Socket类的常用方法

方法说明
public InputStream getInputStream()返回此套接字的输入流
public OutputStream getOutputStream()返回此套接字的输出流
public InetAddress getInetAddress()此套接字连接到的远程 IP 地址;如果套接字是未连接的,则返回 null
public InetAddress getLocalAddress()获取套接字绑定的本地地址
public int getPort()此套接字连接到的远程端口号
public int getLocalPort()返回此套接字绑定到的本地端口
public void close()关闭此套接字
public void shutdownInput()不能在从此套接字的输入流中接收任何数据
public void shutdownOutput()禁用此套接字的输出流

五、TCP网络编程


三次握手

1、TCP是面向连接的可靠协议、通过三次握手建立连接,通讯完成时拆除连接
2、tcp协议 需要先经历三次握手成功之后 在将数据发送给服务器端 确保服务器端是在 在将数据

在这里插入图片描述

TCP协议实现示意图
在这里插入图片描述

客户端发送数据四个步骤:

1、创建 Socket:根据指定服务端的 IP 地址或端口号构造 Socket 类对象。若服务器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常

2、打开连接到 Socket 的输入/出流: 使用 getInputStream()方法获得输入流,使用getOutputStream()方法获得输出流,进行数据传输

3、按照一定的协议对 Socket 进行读/写操作:通过输入流读取服务器放入线路的信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程

4、关闭 Socket:断开客户端到服务器的连接,释放线路

package com.nnfx.test01;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

/**
 * @author 杰仔正在努力
 * @create 2022-12-17 21:26
 */
public class TcpClient {
    public static void main(String[] args) throws IOException {
        /**
         * 1.创建发送端Socket对象(创建连接)
         * 2.获取输出流对象;
         * 3.发送数据;
         * 4.释放资源;
         */
        //1、创建发送端Socket对象(创建连接)
        Socket socket = new Socket(InetAddress.getByName("nnfx.server.com"), 8090);
        //2.获取输出流对象;
        OutputStream outputStream = socket.getOutputStream();
        //3.发送数据;
        outputStream.write("nnfx".getBytes());
        outputStream.close();
        socket.close();
    }
}


服务器端发送数据六个步骤:

1、创建接收端Socket对象

2、监听(阻塞:如果建立连接失败,程序会一直阻塞,不往下执行

3、获取输入流对象

4、获取数据

5、输出数据

6、释放资源

package com.nnfx.test01;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @author 杰仔正在努力
 * @create 2022-12-17 21:31
 */
public class TcpServer {
    public static void main(String[] args) throws IOException {
        /**
         * 1.创建接收端Socket对象;
         * 2.监听(阻塞:如果建立连接失败,程序会一直阻塞,不往下执行;
         * 3.获取输入流对象;
         * 4.获取数据;
         * 5.输出数据;
         * 6.释放资源;
         */
        //1.创建接收端Socket对象;
        ServerSocket serverSocket = new ServerSocket(8090);
        //2.监听客户端发送数据给服务器 如果客户端一直没有发送数据给服务器 导致服务器端会在该方法一直阻塞
        System.out.println("服务器正在等待客户端接收数据。。。。");
        Socket socket = serverSocket.accept();
        //3.获取输入流对象;
        InputStream inputStream = socket.getInputStream();
        byte[] bytes = new byte[1024];
        int len = inputStream.read(bytes);
        System.out.println("服务器端接收客户端发送的数据:" + new String(bytes,len));
        inputStream.close();
        socket.close();
        serverSocket.close();
    }
}

报错

Exception in thread "main" java.net.ConnectException: Connection refused: connect
	at java.net.DualStackPlainSocketImpl.connect0(Native Method)
	at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:75)
	at java.net.AbstractPlainSocketImpl

原因: ip 访问不同 防火墙 没有关闭 或者 只能够在局域网访问


六、UDP网络编程

UDP协议 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据报的方法,俗称面向无连接

核心特点:面向无连接、不可靠的协议 、安全系数很低 容易丢包 但是传输速度是非常快 不需要类似于tcp协议三次握手。 聊天工具


发送数据四个步骤:

1、创建发送端socket对象;

2、提供数据,并将数据封装到数据包中;

3、通过socket服务的发送功能,将数据包发出去;

4、释放资源;

在windows 操作系统中,C:\Windows\System32\drivers\etc\HOSTS 文件中 新增 127.0.0.1 nnfx.server.com

在这里插入图片描述

package com.nnfx.socket;

import java.io.IOException;
import java.net.*;

/**
 * @author 杰仔正在努力
 * @create 2022-12-17 18:29
 */
public class UdpClient {
    public static void main(String[] args) throws IOException {
//        1.创建发送端socket对象;
        DatagramSocket datagramSocket = new DatagramSocket();
//        2.提供数据,并将数据封装到数据包中;
        /**
         * 参数1:发送数据 类型byte数组
         * 参数2:发送数据长度
         * 参数3:发送到服务器端ip地址
         * 参数4:发送服务器端 端口号码
         */
        byte[] msg = "nnfx".getBytes();
        //走dns解析获取ip地址
        InetAddress inetAddress = InetAddress.getByName("nnfx.server.com");
        int port = 8080;
        DatagramPacket datagramPacket = new DatagramPacket(msg, msg.length, inetAddress, port);
//        3.通过socket服务的发送功能,将数据包发出去;
        datagramSocket.send(datagramPacket);
        System.out.println("发送数据成功。。。");
//        4.释放资源;
        datagramSocket.close();
    }
}


接收数据五个步骤:

1、创建接收端socket对象;

2、接收数据;

3、解析数据;

4、输出数据;

5、释放资源;

package com.nnfx.socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * @author 杰仔正在努力
 * @create 2022-12-17 18:46
 */
public class UdpServer {
    public static void main(String[] args) throws IOException {
        /**
         * 1.创建接收端socket对象;
         * 2.接收数据;
         * 3.解析数据;
         * 4.输出数据;
         * 5.释放资源;
         */
        //1、创建接收端socket对象
        //监听端口8080
        int port = 8080;
        DatagramSocket datagramSocket = new DatagramSocket(port);
        //2、接收数据
        byte[] bytes = new byte[1024];
        //数据包的形式接收
        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
        //开始监听客户端发送给服务器端数据,如果没有监听到数据则一直阻塞等待
        System.out.println("开始接受客户端发送的数据....");
        datagramSocket.receive(datagramPacket);
        System.out.println("接收到数据。。。");
        byte[] data = datagramPacket.getData();
        String msg = new String(data);
        //4、输出客户端发送给服务器端的内容
        System.out.println(msg);
        datagramSocket.close();
    }
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值