java网络通信 第一节 建立服务端与本机Telnet通信

网络通信 第一节

  • 解决问题:不同机器,不同程序之间的数据交换

  • IP地址:计算机本机的IP地址:

    • 没有连接网络的话是:127.0.0.1(计算机本机的不跟其他机器进行沟通的)/0.0.0.0
    • 连接了网络的话是:路由器分配的IP地址(局域网分配的IP地址),同一网络中的其他机器可以使用这个IP访问你的机器

局域网分配的IP地址:

在这里插入图片描述

点击右下角wifi图标—>在弹出的标签中左下角右键WLAN—>转到设置—>硬件属性

IPv4:

​ 32位,接近40亿,但是全球60亿人,电子设备包括手机,电脑电视等等是远远不够的。由此诞生128位的IPv6。

网络结构

  • 自己家用的局域网
  • n个局域网组成的城域网,比如一个联通的机房
  • n个城域网组成的广域网

子网掩码

win键—>输入网络状态—>更改适配器选项—>右键WLAN的电脑—>状态(属性中可查看IPv4)—>详细信息

在这里插入图片描述

子网掩码:255.255.255.0

192.168.50.123/24 代表和上掩码意思相同 前24位一致

子网(一个路由器下的子网)的终端 IP前24位一致,后有8位,所以可分配个28个机器。若是有210个机器还需从前面取两位,变为255.255.252.0这样后有10位。

DNS根服务器

  • 根服务器主要用来管理互联网的主目录,全世界只有13台。1个为主根服务器,放置在美国。其余12个均为辅根服务器,其中9个放置在美国,欧洲2个,位于英国和瑞典,亚洲1个,位于日本。所有根服务器均由美国政府授权的互联网域名与号码分配机构ICANN统一管理,负责全球互联网域名根服务器、域名体系和IP地址等的管理。
  • 域名:www.后的,好记忆 IP地址:不好级,经常换 因此有一个域名和IP地址的对照关系使用户能通过域名而不是IP地址来访问网站 例如:百度换了IP地址用户还是可以baidu域名来访问
  • 根服务器中的数据库:存储着域名和IP地址的对照关系表
  • 域名首先需要从根服务器数据库中找到IP地址然后再IP地址加上端口号才能够访问互联网中的一个机器 一个浏览器(谷歌)一天可能要承受大概70亿次访问
  • 全球13个DNS根(rootDNS)服务器信息:

在这里插入图片描述

host

是个持久化的映射表文件

域名除了在根服务器的对照表查找IP外,在本地的host中也存在对照表可以其中设置一个对应关系从而不用去根服务器可以直接访问由于是本地速度更快(抢课专用)

位置:C:\Windows\System32\drivers\etc

由于权限问题需要先复制出来,更改后再放回去覆盖原来的

例子

1.在host中将域名baidu.com的IP地址配置成本机IP地址127.0.0.1 百度域名与IP地址的映射发生变化

2.使用https://baidu.com/访问

3.ping进行测试

可以看到ip地址发现变化 但是往返时间为0没有通信

4.ping www.baidu.com得到百度的IP

可通过IP直接访问(格式:https://14.215.177.39/)

5.在host中改为14.215.177.39 baidu.com(抢课方法)

host在本机 对照表查找速度较快

学校网站ip ping下域名就知道了

socket

  • 套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。
  • 我们将一个小区比作一台计算机,一台计算机里面跑了很多程序,怎么区分程序呢,用的是端口,就好像小区用门牌号区分每一户人家一样。手机送到小明家了,怎么进去呢?从大门进啊,怎么找到大门呢?门牌号呀。不就相当于从互联网来的数据找到接收端计算机后再根据端口判断应该给哪一个程序一样吗。小明家的入口就可以用小区地址+门牌号进行唯一表示,那么同样的道理,程序也可以用IP+端口号进行唯一标识。那么这个程序的入口就被称作Socket。
  • 现在再来说说什么是Socekt编程,我们将TCP协议简化一下,就只有三个核心功能:建立连接、发送数据以及接收数据。我们再来看一下Java中提供的Socket类中的核心功能:

Java-Socket

是不是和TCP协议一样,所以可以把Socket编程理解为对TCP协议的具体实现。

原文链接:https://blog.csdn.net/weixin_43461520/article/details/106240305

  • ServerSocket对象只用来建立连接获得Socket对象
Socket socketclient = scc.accept();

SeverSocket:监听客户端的连接, SeverSocket只是用于建立连接

而Socket对象用于收发数据

OutputStream output = socketclient.getOutputStream();
InputStream input=socketclient.getInputStream();

客户端套接字

  • 客户端套接字使用Socket类建立负责连接到服务器的套接字对象
  • Socket的构造方法 host是服务器IP地址,port是端口号
public Socket(String host, int port)
        throws UnknownHostException, IOException
    {
        this(host != null ? new InetSocketAddress(host, port) :
             new InetSocketAddress(InetAddress.getByName(null), port),
             (SocketAddress) null, true);
    }

通信代码

架构

  • 双端:通信
  • 服务端(serve) 客户端(client)

代码使用

1.端口号

通过IP可以确定所在网络和所在网络终端,一个终端可以有多个进程,不知道消息要发个哪一个进程;就像女朋友告诉你她在几栋但是没告诉你房号是多少。由此出现了端口号,通过IP+端口号可以定位一个程序。

套接字端口号

  • java中通信基于TCP的会使用Socket(套接字),包装了TCP的连接,一个Socket连接需要一个监听他的程序,这个监听它的程序称为服务端,监听它的东西叫做ServerSocket
ServerSocket scc=new ServerSocket(9999);
//会报错将它添加到异常先抛掉main后会出现throws IOException  9999是端口号

9999是端口地址,指定端口号后不需要指定IP地址,在本机运行肯定是本机IP地址

  • 端口号是0-65535有65536个,也就是说可以一个IP地址可以运行65536个程序,但是0-1024最好不要用是一些系统核心功能需要去用的,比如说WEB,通信,打印机,防火墙 ,推荐5000前都不要用

    不放心可以使用netstat -a查看已使用的端口号

在这里插入图片描述

​ 红线右侧是已使用的端口号

  • 还可通过ipconfig查看已使用ip
    在这里插入图片描述

  • Socket方法

scc.accept();
//可以认为是个阻塞方法  阻塞直到有客户端连接上来  
//此方法连接到后会得到一个Socket的返回值所以客户端连接后需要赋值
Socket socketclient=scc.accept();
scc.getInetAddress().getHostAddress() //获取服务端IP地址
scc.getInetAddress() //连接客户端后,才可使用,用于获取客户端IP地址
scc.getLocalSocketAddress() //获取本机端口号
socketclient.getPort() //获取客户端端口号

2.telnet

  • 客户端:windows自带的客户端
  • 我们不创建客户端,直接使用telnet
  • telnet一般默认关闭需要手动开启 win—>设置—>应用—>应用和功能—>右侧上方蓝字程序与功能—>启用或关闭windows功能—>找到telnet开启
  • telnet 127.0.0.1 9999意思是连接到ip地址为127.0.01端口号为9999的服务器

注意:程序不能两次执行,第一次使用的就是9999再执行会冲突

  • 0.0.0.0已经不是一个真正意义上的IP地址了。它表示的是这样一个集合:所有不清楚的主机和目的网络。所以telnet 是无意义的

  • 输入另一个本机地址

在这里插入图片描述

java中:

由于telnet也是在本机上的程序所以telnet的IP也是127.0.0.1

客户端(telnet)服务端住在一个楼(本机ip127.0.0.1) 不在一个房间(端口)

3.传输数据

客户端输入数据至服务端,服务端输出数据至客户端

最基础的IO流:

  • 字节流(output input)
  • 字符流
服务端输出数据至客户端

从客户端Socket获取一个输出流(

OutputStream output=socketclient.getOutputStream();

注意:

1.output.write中为int

output是个字节流为何会有int,是因为byte是从(-128-127),但是字符不会有负的,如果用byte类型只能使用从0-127,综上int类型是为了实现127到255的

2.char是两个字节,byte是一个字节,所以需要两个byte来表示一个char,而String是由char数组组成

在这里插入图片描述

两个byte—>char—>多个char合成一个String

为了方便String封装了getbyte();方法转byte

output.write("Hello Client!!!!".getBytes());

此输出语句,后必须要跟个东西,否则语句结束客户端就会直接退出,无法进入客户端界面,如下

在这里插入图片描述

纠正后:

		output.write("Hello Client!!!!".getBytes());
		while(true) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

结果:

提醒:

ctrl+] 然后在telnet 命令行输入 quit 就可以退出l

客户端输入数据至服务端

从客户端Socket获取一个输入流(),读取在客户端手动输入的值

		InputStream input=socketclient.getInputStream();
		int readnum=input.read();
		System.out.println(readnum);

在这里插入图片描述

第一个a 是我们输入的第二个是通过write写回的

客户端输入/输出流

输入流:程序从输入流读取数据源。

输出流:程序向输出流写入数据。

客户端的输入流:程序从客户端读取数据。

客户端的输出流:程序向客户端写入数据。

4.完整代码展示

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

//**注意**:程序不能两次执行,第一次使用的就是9999再执行会冲突
public class TelnetServer {
	public static void main(String[] args) throws IOException {
		ServerSocket scc = new ServerSocket(9999);
		System.out.println("服务端开启: ip=" + scc.getInetAddress().getHostAddress() + 
				" 端口号=" + scc.getLocalSocketAddress());
		System.out.println("正在等待.........");
		Socket socketclient = scc.accept(); // 可以认为是个阻塞方法 阻塞直到有客户端连接上来
		System.out.println("客户端已连接!"+socketclient.getInetAddress());
		System.out.println("客户端端口号"+socketclient.getPort());

		// 服务端发数据 客户端接受
		OutputStream output = socketclient.getOutputStream();
		//String str;
		output.write("Hello Client!!!!".getBytes());
		
		InputStream input=socketclient.getInputStream();

		while(true) {
			int readnum=input.read();
			System.out.println((char)readnum);
			output.write(("c_to_s:"+(char)readnum).getBytes());
			
		}
//		while(true) {
//			try {
//				Thread.sleep(1000);
//			} catch (InterruptedException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//		}

	}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值