JAVA之旅(三十二)——JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用
GUI写到一半电脑系统挂了,也就算了,最多GUI还有一个提示框和实例,我们暂时不讲了,我们直接来重点吧,关于JAVA的网络请求是怎么实现的?当然是HTTP协议,但是不可否认,他的概念和思想都是我们必须去涉及的,包括后面的tcp和socket等,好吧,我们开车吧!
一.JAVA网络请求概述
关于JAVA的网络请求,我们大致的可以分为以下几个分类
- 网络模式
- OSI
- TCP/IP
- 网络通讯
- IP地址
- 端口号
- 传输协议
拿这些都是干嘛的呢?我们接下来都会讲到
首先我们应该思考的是他们通信的一个过程的步骤
- 1.找到对方IP
- 2.数据发送到指定应用程序上,为了识别,就有了端口的概念
- 3.定义通信协议(也就是后来的传输协议)国际协议/TCP/IP
- 4.三要素:IP,端口,协议
OK,那我们就研究下网络模型,OSI和TCP/IP的区别
其实理解起来也不难,我们看一下他的逻辑结构就知道了
-
OSI
- 应用层
- 表示层
- 会话层
- 传输层
- 网络层
- 数据链路层
- 物理层
-
TCP/IP
- 应用层
- 传输层
- 网络层
- 主机-网络层
应用层,我们就在这里玩,TCP封装了就比较好用,他们都有使用规则,而我们常用的大概就是HTTP协议了
二.IP地址
通讯要素大致的就是这些,我们来说一下我们耳熟能详的IP地址,他是什么概念呢?
-
IP地址
- 网络中设备的标识
- 可用主机名
- 本地回环地址:127.0.0.1,主机名:location
-
端口号
- 用于标识进程的逻辑地址,不同进程的标识
- 有效端口:0-65535,其中0-1024系统使用或者保留,我们熟知的8080
-
通讯协议
- 通讯的规则
- 常见的TCP,UDP
我们可用用代码获得哦,先看API文档,会发现JAVA给我们提供了一个类InetAddress
我们可用直接去用代码使用
try {
InetAddress localHost = InetAddress.getLocalHost();
System.out.println(localHost.toString());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
可以得到
得到的本机的主机名和IP地址
当然,你要单独获取也是没问题的
try {
InetAddress localHost = InetAddress.getLocalHost();
String hostAddress = localHost.getHostAddress();
String hostName = localHost.getHostName();
System.out.println(localHost.toString());
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
三.TCP/UDP通讯协议概述
端口我们没什么可说的,我们直接说通讯协议,目前常见的就是TCP/UDP了,我们先来简单的说下他们的概念
-
TCP
- 建立连接,形成传输数据的通道
- 在连接中进行大数据量传输
- 通过三次握手完成连接,是可靠协议
- 必须建立连接,效率稍微低点
-
UDP
- 将数据及源和目的封装在数据包中,不需要建立连接
- 每个数据包的大小限制在64K内
- 因无连接,是不可靠协议
- 不需要建立连接,速度快
这些这么多,java肯定会给我们封装对象的,这个是毋庸置疑的,那我们接着往下看
四.Socket
Socket就厉害了,我们先来看看他的概念
- Socket就是为网络服务提供的一种机制
- 通信的两端都有socket
- 网络通信其实就是socket通信
- 数据在两个socket通过IO传输
我们现在先说概念,后期再实战
五.UDP传输
UDP传输的socket服务该怎么建立?
- DatagramSocket和DatagramPacket
- 建立发送端和接收端
- 建立数据包
- 调用socket的发送和接收方法
- 关闭socket
客户端和服务端是两个单独的服务,我们可用来用代码讲解下,用到的就是DatagramSocket和DatagramPacket
所以这里应该是有两个,一个传输端,一个接收端
传输端
/**
* 需求: 通过UDP传输方式将一段文字数据发送出去
* 思路:
* 1.建立UDP的socket服务
* 2.建立数据包
* 3.发送数据
* 4.关闭资源
*
* @author LGL
*
*/
public class UdpSend {
public static void main(String[] args) {
try {
// 1.建立UDP的socket服务,通过DatagramSocket对象
DatagramSocket dSocket = new DatagramSocket();
// 2.确定数据,封装成数据包
byte[] data = "udp".getBytes();
DatagramPacket dp = new DatagramPacket(data, data.length,
InetAddress.getByName("192.168.1.102"), 8080);
// 3.发送数据
dSocket.send(dp);
// 4.关闭资源
dSocket.close();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
接收端
/**
* 需求:接收指定端口发送过来的数据
* 思路:
* 1.定义socket服务
* 2.定义数据包,存储接收到的字节数据,因为数据包对象中有更多功能可以提取字节数据中的不同数据信息
* 3.通过socket的receive方法收到的数据存储到数据包中
* 4.将这些不同的数据取出,打印
* 5.关闭资源
*
* @author LGL
*
*/
class UdpRece {
public static void main(String[] args) {
try {
// 1.创建服务,建立端点
DatagramSocket dSocket = new DatagramSocket(8080);
// 2.定义数据包,存储数据
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
// 3.存储
dSocket.receive(dp);
// 4.获取其中的数据
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(), 0, dp.getLength());
int port = dp.getPort();
System.out.println(ip+":" + data + ":" + port);
//5.关闭资源
dSocket.close();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这样就可以通信了
六.多线程UDP聊天应用
既然上面有模有样的写出来了,那我们可以动手写一个应用了,我们继续来看,我不开多个进程,我写一个进程,两个线程来实现聊天
package com.lgl.hellojava;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
/**
* 编写一个聊天应用程序 有收数据和发数据的部分,所以用到多线程的技术,一个接一个发 收和发的动作不一致,所以有两个Runnable
*
* @author LGL
*
*/
public class UdpSpeak {
public static void main(String[] args) {
try {
DatagramSocket sendSocket = new DatagramSocket();
DatagramSocket receSocket = new DatagramSocket(10000);
new Thread(new send(sendSocket)).start();
new Thread(new rece(receSocket)).start();
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 发送
*
* @author LGL
*
*/
class send implements Runnable {
private DatagramSocket socket;
public send(DatagramSocket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
BufferedReader bufr = new BufferedReader(new InputStreamReader(
System.in));
String line = null;
while ((line = bufr.readLine()) != null) {
if ("close".equals(line)) {
break;
}
byte[] buf = line.getBytes();
DatagramPacket dp = new DatagramPacket(buf, buf.length,
InetAddress.getByName("192.168.1.102"), 10000);
socket.send(dp);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 接收
*
* @author LGL
*
*/
class rece implements Runnable {
private DatagramSocket socket;
public rece(DatagramSocket socket) {
this.socket = socket;
}
@Override
public void run() {
while (true) {
try {
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
socket.receive(dp);
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(), 0, dp.getLength());
int port = dp.getPort();
System.out.println(ip + ":" + data + ":" + port);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
OK,搞定,其实主要还是要了解他的思想,编码什么的不重要的
好了,本篇主要是以UDP和概念为起点,而且UDP用的较少,我们一般不是常接触,真正要用的是TCP,所以会重点掌握,那本篇,我们先到这里就好了
JAVA之旅(三十二)——JAVA网络请求,IP地址,TCP/UDP通讯协议概述,Socket,UDP传输,多线程UDP聊天应用的更多相关文章
-
菜鸡的Java笔记 第三十二 - java 静态导入的实现
静态导入的实现 为了理解静态导入的操作产生的动机,下面通过一个具体的代码来观察 范例:现在有一个 Import 的类,这个类中的方法全部都是 static 方法 packa ...
-
JAVA之旅(十二)——Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口
JAVA之旅(十二)--Thread,run和start的特点,线程运行状态,获取线程对象和名称,多线程实例演示,使用Runnable接口 开始挑战一些难度了,线程和I/O方面的操作了,继续坚持 一. ...
-
Java学习笔记【十二、网络编程】
原计划的学习结束时间是3月4日,目前看来已经延迟了,距离低标还差一些,多方面原因,也不找借口,利用周末赶赶进度,争取本周末把低标完成吧! 参考: http://www.runoob.com/java/ ...
-
Python之路(第三十二篇) 网络编程:udp套接字、简单文件传输
一.UDP套接字 服务端 # udp是无链接的,先启动哪一端都不会报错 # udp没有链接,与tcp相比没有链接循环,只有通讯循环 server = socket.socket(socket.AF_I ...
-
Java从零开始学三十二(正则表达式)
一.为什么要有正则 正则表达式可以方便的对数据进行匹配,可以执行更加复杂的字符串验证.拆份.替换功能. 例如:现在要求判断一个字符串是否由数字组成,则可以有以下的两种做法: 不使用正则完成 使用正则完 ...
-
Java基础(三十二)JDBC(2)连接数据库
一.连接数据库的过程 连接数据库的过程:加载数据库驱动程序,不过只需在第一次访问数据库时加载一次,然后在每次访问数据库时创建一个Connection实例,然后执行操作数据库的SQL语句,并返回执行结果 ...
-
JAVA学习第三十二课(经常使用对象API)- 基本数据类型对象包装类
将基本数据类型(8种:int..)封装成对象的优点就是能够在对象中封装很多其它的功能和方法来操控该数据 常见的操作就是:用于基本数据类型与字符串之间的转换 基本数据类型对象包装类一般用于基本类型和字符 ...
-
java 面向对象(三十二):泛型一 泛型的理解
1.泛型的概念所谓泛型,就是允许在定义类.接口时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型.这个类型参数将在使用时(例如,继承或实现这个接口,用这个类型声明变量.创建对象时确定 ...
-
Java从零开始学三十八(JAVA IO- 重定向IO)
一.三个静态变量 java.lang.System提供了三个静态变量 System.in(默认键盘) System.out(默认显示器) System.err 二.重写向方法 System提供了三个重 ...
随机推荐
-
配置本机IIS服务器
1.控制面板---程序---(程序和功能) 安装完成之后就可以访问本地的localhost 2.进入防火墙界面--高级设置 至此开放端口完成
-
BZOJ_1028_[JSOI2007]_麻将_(模拟+贪心)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1028 同一种花色的牌,序数为\(1,2,...,n\).定义"和了"为手上 ...
-
Win2008 R2 IIS7.5+PHP5(FastCGI)+MySQL5环境搭建教程
现在很多朋友想尝试win2008 r2来跑web服务器,跟win2003相比界面差别有点大,有些人可能不太习惯,不过以后是趋势啊,这里简单分享下,方便需要的朋友 准备篇 一.环境说明: 操作系统:Wi ...
-
UE3中的时间
为了管理时间,Unreal将游戏运行时间片分隔为"Ticks".一个Tick是关卡中所有Actors更新的最小时间单位.一个tick一般是10ms-100ms(CPU性能越好,游戏 ...
-
201621123002《java程序设计》第十三周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 为你的系统增加网络功能(购物车.图书馆管理.斗地主等)-分组完成 为了让你的系统可以被多个用户通过网 ...
-
Nagios 使用 NSClient++ 监控Windows Server
在被监控的Windows server 主机上安装NSClinet++下载地址:https://www.nsclient.org/download/32bit:http://files.nsclien ...
-
背景颜色 - bootStrap4常用CSS笔记
.bg-primary 重要的背景颜色 .bg-success 执行成功背景颜色 .bg-info 信息提示背景颜色 .bg-warning 警告背景颜色 .bg-danger 危险背景颜色 .bg- ...
-
pythonNet day07
信号 一个进程向另外一个进程通过信号的方式传递某种讯息,接收方在接收到信号后作出相应的处理 查看信号:kill -l kill -signum PID 给PID的进程发送一个信号 信号名称:信号的名字 ...
-
Python入门基础学习 二
Python入门基础学习 二 猜数字小游戏进阶版 修改建议: 猜错的时候程序可以给出提示,告诉用户猜测的数字偏大还是偏小: 没运行一次程序只能猜测一次,应该提供多次机会给用户猜测: 每次运行程序,答案 ...
-
P1939 【模板】矩阵加速(数列)
题目描述 a[1]=a[2]=a[3]=1 a[x]=a[x-3]+a[x-1] (x>3) 求a数列的第n项对1000000007(10^9+7)取余的值. 输入输出格式 输入格式: 第一行一 ...