Java基础-26(01)总结网络编程

1:网络编程(理解)

(1)网络编程:用Java语言实现计算机间数据的信息传递和资源共享

(2)网络编程模型

(3)网络编程的三要素

A:IP地址

a:点分十进制

网络中计算机的唯一标识。

计算机只能识别二进制的数据,所以我们的IP地址应该是一个二进制的数据。

但是呢,我们配置的IP地址确不是二进制的,为什么呢?

IP:192.168.1.100

换算:11000000 10101000 00000001 01100100

假如真是:11000000 10101000 00000001 01100100的话。

我们如果每次再上课的时候要配置该IP地址,记忆起来就比较的麻烦。

所以,为了方便表示IP地址,我们就把IP地址的每一个字节上的数据换算成十进制,然后用.分开来表示:

"点分十进制"

b:IP地址的组成 网络号段+主机号段

A类:第一号段为网络号段+后三段的主机号段

一个网络号:256*256*256 = 16777216

B类:前二号段为网络号段+后二段的主机号段

一个网络号:256*256 = 65536

C类:前三号段为网络号段+后一段的主机号段

一个网络号:256

c:IP地址的分类

A类 1.0.0.1---127.255.255.254 (1)10.X.X.X是私有地址(私有地址就是在互联网上不使用,而被用在局域网络中的地址) (2)127.X.X.X是保留地址,用做循环测试用的。

B类 128.0.0.1---191.255.255.254 172.16.0.0---172.31.255.255是私有地址。169.254.X.X是保留地址。

C类 192.0.0.1---223.255.255.254 192.168.X.X是私有地址

D类 224.0.0.1---239.255.255.254

E类 240.0.0.1---247.255.255.254

d:特殊的IP地址:

127.0.0.1 回环地址(表示本机)

x.x.x.255 广播地址

x.x.x.0 网络地址

e:dos命令

ipconfig 查看本机ip地址

ping 后面跟ip地址。测试本机与指定的ip地址间的通信是否有问题

f:InetAddress

package cn.itcast_01;

import java.net.InetAddress;

import java.net.UnknownHostException;

/*

* 如果一个类没有构造方法:

* A:成员全部是静态的(Math,Arrays,Collections)

* B:单例设计模式(Runtime)

* C:类中有静态方法返回该类的对象(InetAddress)

* class Demo {

* private Demo(){}

*

* public static Demo getXxx() {

* return new Demo();

* }

* }

*

* 看InetAddress的成员方法:

* public static InetAddress getByName(String host):根据主机名或者IP地址的字符串表示得到IP地址对象

*/

public class InetAddressDemo {

public static void main(String[] args) throws UnknownHostException {

// public static InetAddress getByName(String host)

// InetAddress address = InetAddress.getByName("liuyi");

// InetAddress address = InetAddress.getByName("192.168.12.92");

InetAddress address = InetAddress.getByName("192.168.12.63");

// 获取两个东西:主机名,IP地址

// public String getHostName()

String name = address.getHostName();

// public String getHostAddress()

String ip = address.getHostAddress();

System.out.println(name + "---" + ip);

}

}

B:端口

是应用程序的标识。范围:0-65535。其中0-1024不建议使用。

C:协议:

通信的规则,通信的双方,相互约定好的内容

UDP:适合聊天,不怕丢数据,被限制64kb以内

把数据打包

数据有限制

不建立连接

速度快

不可靠

TCP:适合大数据传输,双方必须经过三次握手确认连接,速度慢

建立连接通道

数据无限制

速度慢

可靠

举例:

UDP:发短信

TCP:打电话

网络编程三要素举例:

我想和林青霞说话了。肿么办?

A:我要找到林青霞。

B:对她说话,要对耳朵说。

C:我说什么呢?"I Love You"

但是,她没学过英语,听不懂。

我没必要说英语,说汉语就可以了:我爱你

(4)Socket服务机制

Socket:网络套接字

Socket编程,网络编程,套接字编程.

Socket包含了:IP地址+端口

Socket原理机制:

通信两端都有Socket.

网络通信其实就是Socket间的通信.

数据在两个Socket间通过IO传输.

(5)UDP协议发送和接收数据(掌握 自己补齐代码)

A:发送:

创建UDP发送端的Socket对象

创建数据并把数据打包

发送数据

释放资源

package cn.itcast_02;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*
 * 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 = "hello,udp,我来了".getBytes();
 // 长度
 int length = bys.length;
 // IP地址对象
 InetAddress address = InetAddress.getByName("192.168.12.92");
 // 端口
 int port = 10086;
 DatagramPacket dp = new DatagramPacket(bys, length, address, port);
 // 调用Socket对象的发送方法发送数据包
 // public void send(DatagramPacket p)
 ds.send(dp);
 // 释放资源
 ds.close();
 }
}

B:接收:

创建UDP接收端的Socket对象

创建数据包用于接收数据

接收数据

解析数据包

释放资源

package cn.itcast_02;(接收)
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*
 * 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(10086);
 // 创建一个数据包(接收容器)
 // 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();
 }
}

(6)TCP协议发送和接收数据(掌握 自己补齐代码)

A:发送:

创建TCP客户端的Socket对象

获取输出流,写数据

释放资源

package cn.itcast_06;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
/*
 * TCP协议发送数据:
 * A:创建发送端的Socket对象
 *  这一步如果成功,就说明连接已经建立成功了。
 * B:获取输出流,写数据
 * C:释放资源
 * 
 * 连接被拒绝。TCP协议一定要先看服务器。
 * java.net.ConnectException: Connection refused: connect
 */
public class ClientDemo {
 public static void main(String[] args) throws IOException {
 // 创建发送端的Socket对象
 // Socket(InetAddress address, int port)
 // Socket(String host, int port)
 // Socket s = new Socket(InetAddress.getByName("192.168.12.92"), 8888);
 Socket s = new Socket("192.168.12.92", 8888);
 // 获取输出流,写数据
 // public OutputStream getOutputStream()
 OutputStream os = s.getOutputStream();
 os.write("hello,tcp,我来了".getBytes());
 // 释放资源
 s.close();
 }
}

B:接收:

创建TCP服务器端的Socket对象

监听客户端连接

获取输入流,读取数据

释放资源

package cn.itcast_06;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
 * TCP协议接收数据:
 * A:创建接收端的Socket对象
 * B:监听客户端连接。返回一个对应的Socket对象
 * C:获取输入流,读取数据显示在控制台
 * D:释放资源
 */
public class ServerDemo {
 public static void main(String[] args) throws IOException {
 // 创建接收端的Socket对象
 // ServerSocket(int port)
 ServerSocket ss = new ServerSocket(8888);
 // 监听客户端连接。返回一个对应的Socket对象
 // public Socket accept()
 Socket s = ss.accept(); // 侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。
 // 获取输入流,读取数据显示在控制台
 InputStream is = s.getInputStream();
 byte[] bys = new byte[1024];
 int len = is.read(bys); // 阻塞式方法
 String str = new String(bys, 0, len);
 String ip = s.getInetAddress().getHostAddress();
 System.out.println(ip + "---" + str);
 // 释放资源
 s.close();
 // ss.close(); //这个不应该关闭
 }
}

(7)案例:

A:UDP

a:最基本的UDP协议发送和接收数据(优化之后的)

package cn.itcast_03;(发送)
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class SendDemo {
 public static void main(String[] args) throws IOException {
 // 创建发送端的Socket对象
 DatagramSocket ds = new DatagramSocket();
 // 创建数据并打包
 byte[] bys = "helloworld".getBytes();
 DatagramPacket dp = new DatagramPacket(bys, bys.length,
 InetAddress.getByName("192.168.12.92"), 12345);
 // 发送数据
 ds.send(dp);
 // 释放资源
 ds.close();
 }
}
package cn.itcast_03;(接收)
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/*
 * 多次启动接收端:
 *  java.net.BindException: Address already in use: Cannot bind
 *  端口被占用。
 */
public class ReceiveDemo {
 public static void main(String[] args) throws IOException {
 // 创建接收端的Socket对象
 DatagramSocket ds = new DatagramSocket(12345);
 // 创建一个包裹
 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);
 // 释放资源
 ds.close();
 }
}

b:把发送数据改进为键盘录入

package cn.itcast_04;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*
 * 数据来自于键盘录入
 * 键盘录入数据要自己控制录入结束。
 */
public class SendDemo {
 public static void main(String[] args) throws IOException {
 // 创建发送端的Socket对象
 DatagramSocket ds = new DatagramSocket();
 // 封装键盘录入数据
 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.12.92"), 12345);
 DatagramPacket dp = new DatagramPacket(bys, bys.length,
 InetAddress.getByName("192.168.12.255"), 12345);
 // 发送数据
 ds.send(dp);
 }
 // 释放资源
 ds.close();
 }
}
package cn.itcast_04;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/*
 * 多次启动接收端:
 *  java.net.BindException: Address already in use: Cannot bind
 *  端口被占用。
 */
public class ReceiveDemo {
 public static void main(String[] args) throws IOException {
 // 创建接收端的Socket对象
 DatagramSocket ds = new DatagramSocket(12345);
 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);
 }
 // 释放资源
 // 接收端应该一直开着等待接收数据,是不需要关闭
 // ds.close();
 }
}
 c:一个简易聊天小程序并用多线程改进
package cn.itcast_05;(1)
import java.io.IOException;
import java.net.DatagramSocket;
/*
 * 通过多线程改进刚才的聊天程序,这样我就可以实现在一个窗口发送和接收数据了
 */
public class ChatRoom {
 public static void main(String[] args) throws IOException {
 DatagramSocket dsSend = new DatagramSocket();
 DatagramSocket dsReceive = new DatagramSocket(12306);
 SendThread st = new SendThread(dsSend);
 ReceiveThread rt = new ReceiveThread(dsReceive);
 Thread t1 = new Thread(st);
 Thread t2 = new Thread(rt);
 t1.start();
 t2.start();
 }
}
package cn.itcast_05;(2)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
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.12.92"), 12345);
 DatagramPacket dp = new DatagramPacket(bys, bys.length,
 InetAddress.getByName("192.168.12.255"), 12306);
 // 发送数据
 ds.send(dp);
 }
 // 释放资源
 ds.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
}
package cn.itcast_05;(3)
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
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();
 }
 }
}

B:TCP

a:最基本的TCP协议发送和接收数据

package cn.itcast_06;(发送)
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
/*
 * TCP协议发送数据:
 * A:创建发送端的Socket对象
 *  这一步如果成功,就说明连接已经建立成功了。
 * B:获取输出流,写数据
 * C:释放资源
 * 
 * 连接被拒绝。TCP协议一定要先看服务器。
 * java.net.ConnectException: Connection refused: connect
 */
public class ClientDemo {
 public static void main(String[] args) throws IOException {
 // 创建发送端的Socket对象
 // Socket(InetAddress address, int port)
 // Socket(String host, int port)
 // Socket s = new Socket(InetAddress.getByName("192.168.12.92"), 8888);
 Socket s = new Socket("192.168.12.92", 8888);
 // 获取输出流,写数据
 // public OutputStream getOutputStream()
 OutputStream os = s.getOutputStream();
 os.write("hello,tcp,我来了".getBytes());
 // 释放资源
 s.close();
 }
}
package cn.itcast_06;(接收)
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
 * TCP协议接收数据:
 * A:创建接收端的Socket对象
 * B:监听客户端连接。返回一个对应的Socket对象
 * C:获取输入流,读取数据显示在控制台
 * D:释放资源
 */
public class ServerDemo {
 public static void main(String[] args) throws IOException {
 // 创建接收端的Socket对象
 // ServerSocket(int port)
 ServerSocket ss = new ServerSocket(8888);
 // 监听客户端连接。返回一个对应的Socket对象
 // public Socket accept()
 Socket s = ss.accept(); // 侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。
 // 获取输入流,读取数据显示在控制台
 InputStream is = s.getInputStream();
 byte[] bys = new byte[1024];
 int len = is.read(bys); // 阻塞式方法
 String str = new String(bys, 0, len);
 String ip = s.getInetAddress().getHostAddress();
 System.out.println(ip + "---" + str);
 // 释放资源
 s.close();
 // ss.close(); //这个不应该关闭
 }
}

b:服务器给出反馈

package cn.itcast_07;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ClientDemo {
 public static void main(String[] args) throws IOException {
 // 创建客户端Socket对象
 Socket s = new Socket("192.168.12.92", 9999);
 // 获取输出流
 OutputStream os = s.getOutputStream();
 os.write("今天天气很好,适合睡觉".getBytes());
 // 获取输入流
 InputStream is = s.getInputStream();
 byte[] bys = new byte[1024];
 int len = is.read(bys);// 阻塞
 String client = new String(bys, 0, len);
 System.out.println("client:" + client);
 // 释放资源
 s.close();
 }
}
package cn.itcast_07;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
 public static void main(String[] args) throws IOException {
 // 创建服务器Socket对象
 ServerSocket ss = new ServerSocket(9999);
 // 监听客户端的连接
 Socket s = ss.accept(); // 阻塞
 // 获取输入流
 InputStream is = s.getInputStream();
 byte[] bys = new byte[1024];
 int len = is.read(bys); // 阻塞
 String server = new String(bys, 0, len);
 System.out.println("server:" + server);
 // 获取输出流
 OutputStream os = s.getOutputStream();
 os.write("数据已经收到".getBytes());
 // 释放资源
 s.close();
 // ss.close();
 }
}

原文发布于微信公众号 - Java帮帮(javahelp)

原文发表时间:2016-12-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏分布式系统进阶

ReplicaManager源码解析1-消息同步线程管理

基本上就是作三件事: 构造FetchRequest, 同步发送FetchRequest并接收FetchResponse, 处理FetchResponse, 这三...

17920
来自专栏熊二哥

快速入门系列--WebAPI--04在老版本MVC4下的调整

WebAPI是建立在MVC和WCF的基础上的,原来微软老是喜欢封装的很多,这次终于愿意将http编程模型的相关细节暴露给我们了。在之前的介绍中,基本上都基于.N...

24860
来自专栏程序员互动联盟

【java网络】IO编程

Prequirement 在继续阅读这篇文章之前,请务必先阅读前面这篇Java IO概述,因为Java把所有的IO都统一成流(Stream)了。 TCP/IP协...

40980
来自专栏Android知识点总结

基于UDP的网络数据传输测试(Java+Android)

31750
来自专栏比原链

剥开比原看代码02:比原启动后去哪里连接别的节点

Gitee地址:https://gitee.com/BytomBlockchain/bytom

13220
来自专栏腾讯云API

腾讯云API:用Python使用腾讯云API(cvm实例)

腾讯云API地址:https://cloud.tencent.com/document/api

86040
来自专栏知识分享

java 之UDP编程

大白话:每一台电脑都有自己的ip地址,向指定的ip地址发数据,数据就发送到了指定的电脑。UDP通信只是一种通信方式而已,其特点就不多说。有了ip地址数据就能发送...

31240
来自专栏Java成神之路

Java之网络编程笔记

  IP地址:用于标记一台计算机的身份证。 IP地址由网络地址(确定网络)和主机地址(网络中的主机)组成。

12020
来自专栏java初学

II 3.1 连接到服务器

432110
来自专栏有趣的django

37.Django1.11.6文档

第一步 入门 检查版本 python -m django --version 创建第一个项目 django-admin startproject mysite ...

51880

扫码关注云+社区

领取腾讯云代金券