Java中网络编程概述、IP地址、端口号、TCP和UDP协议、Socket、UDP传输、多线程UDP聊天

网络编程概述

就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换。

有人说,20世纪最伟大的发明不是计算机,而是计算机网络。哈哈,的确是这样,现在没有网,简直不能活下去。

计算机之间要进行通讯的话要以什么样的规则进行通信呢,这就是网络模型研究的问题,我们下来学习。

网络模型

  • OSI参考模型
  • TCP/IP参考模型

OSI参考模型

应用层
表示层
会话层
传输层
网络层
数据链路层
物理层

TCP/IP参考模型

应用层
传输层
网络层
主机至网络层 

网络通信三要素

  • IP地址:InetAddress
    • 网络中设备的标识,不易记忆,可用主机名
  • 端口号
    • 用于标识进程的逻辑地址,不同进程的标识
  • 传输协议
    • 通讯的规则
      常见协议:TCP,UDP

IP地址

说起IP地址,我们每个人都知道自己的电脑有个IP地址,它在计算机中有什么作用呢?我们就来看一下它的具体概念
要想让网络中的计算机能够互相通信,必须为每台计算机指定一个标识号,也就是网络中计算机的唯一标识,通过这个标识号来指定要接受数据的计算机和识别发送的计算机,在TCP/IP协议中,这个标识号就是IP地址。

那么,我们如何获取和操作IP地址呢?java提供了一个类**InetAddress **供我们使用对IP地址的获取和操作。

我们来获取本机的主机名和IP地址

public class InetAddressDemo { 
public static void main(String[] args) { 
try { 
InetAddress in = InetAddress.getLocalHost(); System.out.println(in.toString()); 
} catch (UnknownHostException e) { 
e.printStackTrace(); 
}
 }
}

运行程序,我们就得到了本机的主机名和IP地址
那么我们想要知道别人的IP地址或主机名怎么办呢?当然也是有方法的

public class InetAddressDemo { 
public static void main(String[] args) throws UnknownHostException { InetAddress address = InetAddress.getByName("192.168.2.102"); 
// public String getHostName()获取主机名,
 String name = address.getHostName(); 
// public String getHostAddress()获取IP地址 
String ip = address.getHostAddress(); 
System.out.println(name + "---" + ip); 
}
}

如果你和别人在一个局域网内,知道了他的主机名或者IP地址就可以获取到另外一个。

端口号

端口号它分为两种,一种是物理端口,另外一种是逻辑端口。
物理端口就是网卡口,我们要学的呢就是逻辑端口,它是什么呢?

  • 每个网络程序都会至少有一个逻辑端口
  • 用于标识进程的逻辑地址,不同进程的标识
  • 有效端口:065535,其中01024系统使用或保留端口。

TCP和UDP协议

TCP和UDP协议它们是通讯的规则,它们有什么区别呢?

TCP
    建立连接,形成传输数据的通道
    在连接中进行大数据量传输
    通过三次握手完成连接,是可靠协议
    必须建立连接,效率会稍低
UDP
    将数据源和目的封装成数据包中,不需要建立连接
    每个数据包的大小在限制在64k
    因无连接,是不可靠协议
    不需要建立连接,速度快

一般的软件它既有UDP,又有TCP,用TCP来保证软件的可靠性,用UDP来保证软件的传输速度快。

Socket

我们继续看Socket,我们说的网络编程也就是Socket编程也叫做网络套接字。

  • Socket套接字:
    • 网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的标识符套接字。
  • Socket原理机制:
    • 通信的两端都有Socket。
    • 网络通信其实就是Socket间的通信。
    • 数据在两个Socket间通过IO传输。

UDP传输

我们要用UDP传输数据时,怎么用Socket建立连接呢?

  • DatagramSocket与DatagramPacket
  • 建立发送端,接收端。
  • 建立数据包。
  • 调用Socket的发送接收方法。
  • 关闭Socket。

发送端与接收端是两个独立的运行程序。我们用代码实现一个UDP传输数据的例子

UDP传输-发送端

/* 
* 需求:接收指定端口发送过来的数据
 * 
* UDP协议发送数据:
* A:创建发送端Socket对象 
* B:创建数据,并把数据打包
* C:调用Socket对象的发送方法发送数据包 
* D:释放资源 
*/
public class SendDemo { 
public static void main(String[] args) throws IOException { 
// 创建发送端Socket对象 
// DatagramSocket() 
DatagramSocket ds = new DatagramSocket();
 // 创建数据,并把数据打包 
// DatagramPacket(byte[] buf, int length, InetAddress address, int port) 
// 创建数据 
byte[] bys = "UDP过来了".getBytes();
 // 长度 
int length = bys.length;
 // IP地址对象 
InetAddress address = InetAddress.getByName("192.168.2.102"); 
// 端口
 int port = 12345; 
DatagramPacket dp = new DatagramPacket(bys, length, address, port); 
// 调用Socket对象的发送方法发送数据包 
// public void send(DatagramPacket p) 
ds.send(dp); 
// 释放资源
 ds.close();
 }
}

UDP传输-接收端

/* * UDP协议接收数据: 
* A:创建接收端Socket对象 
* B:创建一个数据包(接收容器) 
* C:调用Socket对象的接收方法接收数据 
* D:解析数据包,并显示在控制台 
* E:释放资源 
*/
public class ReceiveDemo { 
public static void main(String[] args) throws IOException {
 // 创建接收端Socket对象 
// DatagramSocket(int port) 
DatagramSocket ds = new DatagramSocket(12345); 

// 创建一个数据包(接收容器) 
// DatagramPacket(byte[] buf, int length) 
byte[] bys = new byte[1024]; 
int length = bys.length; 
DatagramPacket dp = new DatagramPacket(bys, length); 

// 调用Socket对象的接收方法接收数据 
// public void receive(DatagramPacket p)
 ds.receive(dp); // 阻塞式 

// 解析数据包,并显示在控制台 
// 获取对方的ip 
// public InetAddress getAddress() 
InetAddress address = dp.getAddress(); 
String ip = address.getHostAddress(); 
// public byte[] getData():获取数据缓冲区 
// public int getLength():获取数据的实际长度
 byte[] bys2 = dp.getData(); 
int len = dp.getLength();
String s = new String(bys2, 0, len);
 System.out.println(ip + "传递的数据是:" + s); 
// 释放资源 
ds.close(); 
}
}

我们先运行接收端的代码,再运行发送端的代码,这样在接收端就会收到由发送端发过来的数据。完成了UDP传输

多线程UDP聊天

/* 
* 通过多线程实现聊天程序,我们就要开启两个线程,一个接收数据,一个发送数据,这样我就可以实现在一个窗口发送和接收数据了 
*/
public class ChatRoom { 
public static void main(String[] args) throws IOException { DatagramSocket dsSend = new DatagramSocket(); 
DatagramSocket dsReceive = new DatagramSocket(12345); SendThread st = new SendThread(dsSend); 
ReceiveThread rt = new ReceiveThread(dsReceive);
 Thread t1 = new Thread(st); 
Thread t2 = new Thread(rt);
 t1.start(); t2.start(); 
}
}
/* * 接收数据 */
public class ReceiveThread implements Runnable {
 private DatagramSocket ds;
 public ReceiveThread(DatagramSocket ds) {
 this.ds = ds;
 } 
@Override
 public void run() { 
try { while (true) { 
// 创建一个包裹 
byte[] bys = new byte[1024]; 
DatagramPacket dp = new DatagramPacket(bys, bys.length); 
// 接收数据 ds.receive(dp);
 // 解析数据
 String ip = dp.getAddress().getHostAddress(); 
String s = new String(dp.getData(), 0, dp.getLength()); System.out.println("from " + ip + " data is : " + s);
 } 
} catch (IOException e) { 
e.printStackTrace(); 
} 
}
}
/* * 发送数据 */
public class SendThread implements Runnable { 
private DatagramSocket ds; 
public SendThread(DatagramSocket ds) { 
this.ds = ds; 
} 
@Override 
public void run() { 
try { 
// 封装键盘录入数据
 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
String line = null; 
while ((line = br.readLine()) != null) { 
if ("886".equals(line)) { 
break; 
} 
// 创建数据并打包
 byte[] bys = line.getBytes(); 
DatagramPacket dp = new DatagramPacket(bys, bys.length,InetAddress.getByName("192.168.2.102"), 12345); 
// 发送数据 
ds.send(dp); 
} 
// 释放资源 
ds.close(); 
} catch (IOException e) { 
e.printStackTrace(); 
} 
}
}

我们只需要运行聊天室ChatRoom类,就可以完成单窗口聊天了
这里写图片描述

你发送一句,他就会接收一句,是不是很有意思呢?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335

推荐阅读更多精彩内容

  • 名词延伸 通俗的说,域名就相当于一个家庭的门牌号码,别人通过这个号码可以很容易的找到你。如果把IP地址比作一间房子...
    杨大虾阅读 20,569评论 2 57
  • 同样的,本文篇幅也比较长,先来一张思维导图,带大家过一遍。 一、 计算机网络体系结构分层 二、 TCP/IP 基础...
    涤生_Woo阅读 64,780评论 38 1,039
  • 个人认为,Goodboy1881先生的TCP /IP 协议详解学习博客系列博客是一部非常精彩的学习笔记,这虽然只是...
    贰零壹柒_fc10阅读 5,042评论 0 8
  • 1.这篇文章不是本人原创的,只是个人为了对这部分知识做一个整理和系统的输出而编辑成的,在此郑重地向本文所引用文章的...
    SOMCENT阅读 13,028评论 6 174
  • 1.1 TCP/IP协议组 TCP/IP协议(传输控制协议)由网络层的IP协议和传输层的TCP协议组成 IP层负责...
    F麦子阅读 2,779评论 0 25