网络编程基础

基础知识

网络通信

概念:两台或多台设备进行数据的传输。

网络

概念:两台或多台设备通过一定物理设备连接来构成网络。
网络的分类:

- 局域网:(范围逐渐变大),一个小型区域
- 城域网:一个城市
- 广域网:一个国家(典型代表是局域网)

网络编程的目的

网络编程的目的:直接或间接地通过网络协议与其他计算机实现数据交换进行通讯
要想实现网络编程,需要关注两个问题:

1.如何准确定位网络上的一台或多台主机,定位主机上的特定应用
2.找到主机以后怎么进行可靠高效的数据传输

IP地址

  1. 概念:唯一标识主机的。
  2. 查看ip地址:ipconfig
    主机地址查看
  3. IP地址表示:4个字节(32位)表示,一个字节的范围是0~255;
  4. IP地址的格式:网络地址+主机地址。
  5. IPV6地址(解决了IPV4在网络地址上的资源有限问题),IPV6可以实现多种接入设备连入互联网。 IPV6是由128位(128/16 = 8字节)表示一个地址。

域名

  1. www.baidu.com着就是百度的域名,他可以理解成是IP地址的映射(因为ip地址不容易记忆,所以就有域名的出现)

端口

概念:用于标识计算机上某个特定的网路程序。
端口号:范围0~65535.
电脑浏览器如果想访问一个网站需要通过(IP+端口号)
访问
在网络开发中最好不要使用0~1024号端口,因为这些端口可能已经被其他服务器使用了
常见端口号

  • 一个服务要接收和发送数据的话,需要有一个端口。端口就类似于人的耳朵,我们要听懂别人的话,必须要有耳朵

网络通信协议

在这里插入图片描述

TCP协议于UDP协议的区别

  • TCP类似于打电话
  • UDP类似于发短信

TCP 协议:传输控制协议

就是确定是否连接成功,需要进行三次确认。

  • TCP协议的优点:需要进行三次握手(是可靠的)
  • 缺点就是效率低。
    简单理解TCP协议

UDP协议:用户数据协议

  • UDP协议无法保证传输的数据一定被接收到
  • UDP协议就是没有确认对方是否能够接收到消息,就直接传输信息
  • 比如说:你发送信息给别人,但是这个电话号码可能停机了或者说注销了,你不能确保别人能接收消息,类似于UDP协议
  • 在这里插入图片描述
    假如说现在有一个人也想要打电话给kim,由于kim这个时候在和tom打电话,他们两个如果电话没有挂掉,这个人的电话是打不通的,就类似于TCP协议要释放已经建立的连接

tom发信息给kim,另外一个人同样也可以发信息给kim,就类似于UDP协议不需要释放资源
在这里插入图片描述

简单的API使用

InetAddress

一个InetAddress类的对象就当于是一个IP地址

相关方法

getByName(String host) 、 getLocalHost()
两个常用方法:getHostName() 获取域名 / getHostAddress() 获取主机地址

实例

例子

代码
package 网络编程;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class API {

    public static void main(String[] args) throws UnknownHostException {
        //获取本机的IntetAddress的对象
        InetAddress localHost = InetAddress.getLocalHost();
        System.out.println(localHost);

        //根据指定主机名,获取InetAddress对象
        InetAddress host1 = InetAddress.getByName("LAPTOP-612T08NP");
        System.out.println(host1);

        //根据域名返回InetAddress对象,比如百度的域名
        InetAddress host2 = InetAddress.getByName("www.baidu.com");
        System.out.println(host2);

        //根据域名获取Ip
        String hostAddress = host2.getHostAddress();
        System.out.println("host2 对应的IP = "+ hostAddress);
    }
}

常用的方法就是上面四种,分别来获取IP和对应的域名。

Socket理解

- Socket就类似于通信的通道,发送数据是通过socket
- TCP编程:可靠的,但是效率低
- UDP编程:不可靠的,但是效率高

简单理解就是数据两端的插头,让客户端与服务器端可以很好的取得连接。目的就是为了通信,而通信的目的就是用来发送数据和接收数据。

socket传输协议

TCP网络通信案例

案例一:使用字节流。编写一个服务器端和一个客户端,服务器端在9999端口进行监听,客户端连接到服务器端发送一个“hello world”然后退出,服务器端接收到客户端的信息输出并退出。
思路分析

服务端:


package 网络编程;

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

public class SocketTCPServer {
    public static void main(String[] args) throws IOException {
        //在本机9999端口接听,等待连接
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务器,在9999端口监听,等待连接。。。");
        //当没有客户端连接999端口时,程序会阻塞,等待连接
        //如果有客户端连接。则会返回Socket对象,程序继续
        Socket socket = serverSocket.accept();

        System.out.println("socket = "+socket.getClass());
    }
}

在这里插入图片描述
此时9999端口已经占用了,如果再次点击运行,程序会报错。在这里插入图片描述

案例1:TCP编写(字节读写)

案例要求:

案例要求

客户端:
- 连接服务端(IP,端口)
- 连接上后,生成Socket,通过socket.getOutputStream()函数创建输出流
- 通过输出流,写入数据到数据通道(服务器端来接收)
package 网络编程;

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

public class SocketTCPClient {
    public static void main(String[] args) throws IOException {
        //连接TCP端(ip,端口)
        //连接本机9999端口,如果连接成功,返回socket对象
        Socket socket = new Socket(InetAddress.getLocalHost(),9999);
        System.out.println("客户端 socked返回"+socket.getClass());
        //连接成功后,生成socket对象,通过socket.getOutputStream()(输出流)输出hello server
        //得到和socket对象关联的输出流对象
        OutputStream outputStream = socket.getOutputStream();
        //通过输出流,写入数据到数据通道
        outputStream.write("hello server".getBytes());
        //关闭流对象的socket,
        outputStream.close();
        socket.close();
        System.out.println("客户端退出!");




    }
}

服务端
- 在本机的9999 端口监听,等待连接
- 当没有客户端连接9999 端口时,程序会阻塞,等待连接
- 通过socket.getInputStream();函数来读取客户端写入到数据通道的数据,然后显示出来。
package 网络编程;

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

public class SocketTCPServer {
    public static void main(String[] args) throws IOException {
        //在本机9999端口接听,等待连接
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务器,在9999端口监听,等待连接。。。");
        //当没有客户端连接999端口时,程序会阻塞,等待连接
        //如果有客户端连接。则会返回Socket对象,程序继续
        Socket socket = serverSocket.accept();

        System.out.println("服务器 socket = "+socket.getClass());
        //通过输入流来读取客户端传来的数据
        InputStream inputStream = socket.getInputStream();
        //IO读取
        byte[] buf = new byte[1024];
        int readLen = 0;
        while ((readLen = inputStream.read(buf)) != -1){
            System.out.println(new String(buf,0,readLen));//根据
        }
        //关闭流
        inputStream.close();
        socket.close();
        serverSocket.close();
        
    }
}


注意事项
  • 运行程序的时候一定是先运行server段,再运行client客户端

案例2

思路解析
服务端
新添加两行代码

package 网络编程;

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

public class SocketTCPServer {
    public static void main(String[] args) throws IOException {
        //在本机9999端口接听,等待连接
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务器,在9999端口监听,等待连接。。。");
        //当没有客户端连接999端口时,程序会阻塞,等待连接
        //如果有客户端连接。则会返回Socket对象,程序继续
        Socket socket = serverSocket.accept();

        System.out.println("服务器 socket = "+socket.getClass());
        //通过输入流来读取客户端传来的数据
        InputStream inputStream = socket.getInputStream();
        //IO读取
        byte[] buf = new byte[1024];
        int readLen = 0;
        while ((readLen = inputStream.read(buf)) != -1){
            System.out.println(new String(buf,0,readLen));//根据
        }

        //获取socket相关联的输出流
        OutputStream outputStream =  socket.getOutputStream();
        //写入数据到数据通道
        outputStream.write("hello,client".getBytes());
        //关闭流
        inputStream.close();
        socket.close();
        serverSocket.close();
        //关闭输出流
        outputStream.close();
        
    }
}


在这里插入图片描述

  • server端有输出,但是没有退出,好像是卡到了什么地方。clint并没有接收到server端发送的数据。
  • 如何解决上面的问题,就是给两个端设置结束标志。socket。shutdownOutput();关闭了输出的结束。

server端
clint端

代码优化

服务端:

package 网络编程;

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

public class SocketTCPServer {
    public static void main(String[] args) throws IOException {
        //在本机9999端口接听,等待连接
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务器,在9999端口监听,等待连接。。。");
        //当没有客户端连接999端口时,程序会阻塞,等待连接
        //如果有客户端连接。则会返回Socket对象,程序继续
        Socket socket = serverSocket.accept();

        System.out.println("服务器 socket = "+socket.getClass());
        //通过输入流来读取客户端传来的数据
        InputStream inputStream = socket.getInputStream();
        //IO读取
        byte[] buf = new byte[1024];
        int readLen = 0;
        while ((readLen = inputStream.read(buf)) != -1){
            System.out.println(new String(buf,0,readLen));//根据
        }

        //获取socket相关联的输出流
        OutputStream outputStream =  socket.getOutputStream();
        //写入数据到数据通道
        outputStream.write("hello,client".getBytes());
        //设置结束标志
        socket.shutdownOutput();
        //关闭流
        inputStream.close();
        socket.close();
        serverSocket.close();
        //关闭输出流
        outputStream.close();
        
    }
}

客户端:

package 网络编程;

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

public class SocketTCPClient {
    public static void main(String[] args) throws IOException {
        //连接TCP端(ip,端口)
        //连接本机9999端口,如果连接成功,返回socket对象
        Socket socket = new Socket(InetAddress.getLocalHost(),9999);
        System.out.println("客户端 socked返回"+socket.getClass());
        //连接成功后,生成socket对象,通过socket.getOutputStream()(输出流)输出hello server
        //得到和socket对象关联的输出流对象
        OutputStream outputStream = socket.getOutputStream();
        //通过输出流,写入数据到数据通道
        outputStream.write("hello server".getBytes());
        //设置结束标志
        socket.shutdownOutput();
        //获取和socket关联的输入流,读取数据(字节),并显示
        InputStream inputStream = socket.getInputStream();
        byte[] buf = new byte[1024];
        int readLen = 0;
        while ((readLen = inputStream.read(buf)) != -1){
            System.out.println(new String(buf,0,readLen));//根据
        }
        //关闭流对象的socket,
        outputStream.close();
        socket.close();
        System.out.println("客户端退出!");
        //关闭输入流
        inputStream.close();




    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仰望星空的鑫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值