1.> 计算机网络:
☆ 那分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息。
i. 共享硬件、软件、数据信息等资源。
2.> 计算机网络的主要功能:
☆ 资源共享、信息传输与集中处理、均衡负荷与分布处理、综合信息服务(www/综合业务数字网络 ISDN)。
3.> 网络通络协议:
☆ 计算机网络中现实通信必须有一些约定即通信协议,对速率、传输代码、代码结构、传输控制步骤、出错控制等制定了标准。
4.> 网络通信接口:
☆ 为了使两个结点之间能进行对话,必须在它们之间建立通信(即接口),使彼此之间能进行信息交换。接口包括两部分:
i. 硬件装置:实现节点之间信息传送
ii. 软件装置:在归定双方进行通信的约定协议
5.> 分层:
☆ 由于结点之联系很复杂,在制定协议时,把复杂成份分解成了一些简单的成份,再将它们复合起来:最常用的复合方式是层次方式,即同层可以通信、上一层可以调下一层而与再下一层不发生关系。各层互不影响,利于系统的开发和扩展。
6.> 通信协议的分层归定:
☆ 把用户应用层程序作为最高层,把物理通信线路作为最低层,将其间的协议处理分为若干层,规定每层处理的任务,也规定每层的接口标准。
☆ 参考模型:OSI开放式系统互联 OSI全写:OpenSystem Interconnection城大幅度实际当中的应用只有上图右边四层的标准,右图不是国际化中的标准,是事实上的标准。
☆ [暂无找到对应处理(封装、拆封的图片)]
7.> IP协议:
☆ IP(Internet Protocol)协议是网际的主要协议,支持网间互连的数据报通信。它提供主要动能
i. 无线数据报传送
ii. 数据报路由选择和差错控制
iii. 提供了独一无二的IP地址
☆ [暂无找到对应的IP地址模型图片]
☆ TCP(transmission control protocol)
i. 是专门设计用于在不可靠的因特网上提供可靠的、端到端的字节流通信的协议。它是一种面向连接的协议。TCP连接是字节流而非报文流。
☆ UDP(user data protocol)
i. UDP向应用程序提供了一种发送封装的原始IP数据报的方法、并且发送时无需建立连接。是一种不可靠的连接。
8.> Socket:
☆ Socket的概念:
i. 两个Java应用程序可通过一个双向的网络通信的连接实现数据交互,这个双向链接的一端称为一个Socket。
ii. Socket通常用实现client-server连接。
iii. Java.net包中定义了两个类Socket和ServerSocket,分别用来实现双向连接的client和server端
iv. 建立组件连接时所需要的寻址信息为远程计算机的IP地址和端口号(Port number)
☆ 端口号:
i. 端口号用来区分计算机中不同的应用程序,端口号在计算机内部才用两个字节来表示,两个最字节点,最多有65535端号。
ii. 端口号有一个应用程序,已经占用了,其它的应用程序就不可以占用,自己编写的程序要用1024以上的,1024以下的系统会随时征用。
iii. 著名端名号:
1. 80端口: http协议端口
2. 21端口: ftp文件传输协议
3. 25 smtp 简单邮件传输协议(SMTP) ……
4. 端口号分TCP端口、UDP端口,每种都是65535
9.> Java程序实现TCP/IP网络通信:
ii. 客户端代码实现:
☆ 实现1:由客户端向服务端发送通信
i. 服务器端代码实现:
package com.socket.tcp.test;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServer {
public static void main(String [] args) throws IOException{
// 创建一个阻塞的server端的Socket 绑定端口号6666
ServerSocket serverSocket = new ServerSocket(6666);
// 侦听并接受该Socket的连接
// 服务器和客户端socket创建连接,每一个连接都为一个accept,接收所有的客户端连接
while(true){
Socket socket = serverSocket.accept();
//以流的方式进行处理
InputStream is = socket.getInputStream();
DataInputStream dis = new DataInputStream(is);
// 打印客户端,发送的信息
System.out.println(dis.readUTF());
}
}
}
ii.
客户端代码实现:
package com.socket.tcp.test;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class TestClinet {
public static void main(String[] args){
try {
// 创建一个流套接字并将其连接到指定 IP 地址的指定端口号
Socket socket = new Socket("127.0.0.1",6666);
OutputStream os =socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
// 向服务器发送数据
dos.writeUTF("hello Server");
dos.flush();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
iii. 运行结果:
先启动服务端,再启动客户端,现在用cmd端口来启动服务端与客户端。
服务端运行结果:
客户端运行结果:
☆ 实现2:由客户端向服务端发送通信:
i. 服务端代码实现:
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServer {
public static void main(String[] args) {
try {
// // 创建一个阻塞的server端的Socket 绑定端口号6666
ServerSocket serverSocket = new ServerSocket(6666);
while(true){
// 服务器和客户端socket创建连接,每一个连接都为一个accept,接收所有的客户端连接
Socket socket = serverSocket.accept();
// 向端客户发出信息
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF("hello," + socket.getInetAddress() +" port: " + socket.getPort() +"bye bye!");
dos.flush();
dos.close();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("程序运行出错……");
}
}
}
ii. 客户端代码实现:
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class TestClient {
public static void main(String[] args) {
try {
// 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
Socket socket = new Socket("127.0.0.1",6666);
// 返回此套接字的输入流
InputStream is = socket.getInputStream();
DataInputStream dos = new DataInputStream(is);
// 打印 输入流的内容
System.out.println(dos.readUTF());
dos.close();
is.close();
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
System.out.println("服务器连接失败!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
iii.
运行结果:
先启动服务端,再启动客户端,现在用cmd端口来启动服务端与客户端。
服务端运行结果:
客户端运行结果:
☆ 实现3:客户端与服务端相互通信:
i. 服务端代码实现:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServer {
public static void main(String[] args) {
InputStream is = null;
OutputStream os = null;
try {
// 创建绑定到特定端口的服务器套接字。
ServerSocket serverSocket = new ServerSocket(8888);
// 侦听并接受到此套接字的连接。
Socket socket = serverSocket.accept();
// 返回此套接字的输入流。
is = socket.getInputStream();
// 返回此套接字的输出流。
os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
DataInputStream dis = new DataInputStream(is);
// 读取从客户端发送的信息
String s = null;
if((s= dis.readUTF())!= null){
System.out.println(s);
System.out.println("from : " + socket.getInetAddress());
System.out.println("prot : "+ socket.getPort());
}
//向客户端发送信息
dos.writeUTF("hi, hello");
// 关闭此输入流并释放与该流关联的所有系统资源。
dis.close();
dos.flush();
dos.close();
// 关闭此套接字。
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ii.
客户端代码实现: import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class TestClient {
public static void main(String [] args){
// 定义输入、输出流对象
InputStream is = null;
OutputStream os = null;
try {
// 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
Socket socket = new Socket("127.0.0.1",8888);
// 获得 此套接字的输入、输出流。
is = socket.getInputStream();
os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
DataInputStream dis = new DataInputStream(is);
// 向服务器端发送信息
dos.writeUTF("hai");
// 读取服务器返回的信息
String s = null;
if((s = dis.readUTF()) != null){
System.out.println(s);
}
// 刷新此输出流并强制写出所有缓冲的输出字节。
dos.flush();
// 关闭此输出流并释放与此流有关的所有系统资源。
dos.close();
// 关闭此输入流并释放与该流关联的所有系统资源。
dis.close();
// 关闭套接字
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
iii.
运行结果:
先启动服务端,再启动客户端,现在用cmd端口来启动服务端与客户端。
服务端运行结果:
客户端运行结果:
10.> Java程序实现UDP网络通信:
☆ UDP协议的特点:
i. 不可靠的、效率高、数据报/非连接
ii. upd server本身没有客户端与服务端的概念,不区客户端的Socket和服务端的Socket
☆ 实现1:客户端与服务端相互通信
i. 服务器端代码实现:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TestServer {
public static void main(String[] args) {
InputStream is = null;
OutputStream os = null;
try {
// 创建绑定到特定端口的服务器套接字。
ServerSocket serverSocket = new ServerSocket(8888);
// 侦听并接受到此套接字的连接。
Socket socket = serverSocket.accept();
// 返回此套接字的输入流。
is = socket.getInputStream();
// 返回此套接字的输出流。
os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
DataInputStream dis = new DataInputStream(is);
// 读取从客户端发送的信息
String s = null;
if((s= dis.readUTF())!= null){
System.out.println(s);
System.out.println("from : " + socket.getInetAddress());
System.out.println("prot : "+ socket.getPort());
}
//向客户端发送信息
dos.writeUTF("hi, hello");
// 关闭此输入流并释放与该流关联的所有系统资源。
dis.close();
dos.flush();
dos.close();
// 关闭此套接字。
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ii. 客户端代码实现:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class TestClient {
public static void main(String [] args){
// 定义输入、输出流对象
InputStream is = null;
OutputStream os = null;
try {
// 创建一个流套接字并将其连接到指定 IP 地址的指定端口号。
Socket socket = new Socket("127.0.0.1",8888);
// 获得 此套接字的输入、输出流。
is = socket.getInputStream();
os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
DataInputStream dis = new DataInputStream(is);
// 向服务器端发送信息
dos.writeUTF("hai");
// 读取服务器返回的信息
String s = null;
if((s = dis.readUTF()) != null){
System.out.println(s);
}
// 刷新此输出流并强制写出所有缓冲的输出字节。
dos.flush();
// 关闭此输出流并释放与此流有关的所有系统资源。
dos.close();
// 关闭此输入流并释放与该流关联的所有系统资源。
dis.close();
// 关闭套接字
socket.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
iii. 运行结果:
先启动服务端,再启动客户端,现在用cmd端口来启动服务端与客户端。
服务端运行结果:
客户端运行结果:
☆ 实现2:由客户端向服务端发送long类型的数据:
i. 服务端代码实现:
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
/**
* 服务端接收long类型的数据
* @ClassName: TestServer
* @Description: TODO
* @author yuanxw
* @date 2013-2-4 16:50:51
*/
public class TestServer {
public static void main(String [] args){
// 构建一个byte数组,长度为1024
byte buf[] = new byte[1024];
// DatagramPacket 此类表示数据报包,数据报包用来实现无连接包投递服务。
// 每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。
// 从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。
DatagramPacket packet = new DatagramPacket(buf,buf.length);
try {
// 用来发送和接收数据报包的套接字。
// 构造数据报套接字并将其绑定到本地主机上任何可用的端口。
DatagramSocket socket = new DatagramSocket(8888);
// 从此套接字接收数据报包。
socket.receive(packet);
// 创建一个 ByteArrayInputStream,使用 buf 作为其缓冲区数组。
ByteArrayInputStream stream = new ByteArrayInputStream(buf);
DataInputStream dis = new DataInputStream(stream);
// 将数据以long格式进行解析。
System.out.println(dis.readLong());
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ii. 客户端代码实现:
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketException;
/**
* 将long类型的数据,发送到的服务端
* @ClassName: TestClient
* @Description: TODO
* @author yuanxw
* @date 2013-2-4 16:50:42
*/
public class TestClient {
public static void main(String [] args) throws InterruptedException, IOException {
// 声明一个long类型的变量
long n = 100000L;
// 创建一个新的 byte 数组输出流。
ByteArrayOutputStream stream = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(stream);
// 将一个 long 值以 8-byte 值形式写入基础输出流中,先写入高字节。
dos.writeLong(n);
// 将long类型转成byte数组
byte [] buf = stream.toByteArray();
try {
// 构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
DatagramPacket packet = new DatagramPacket(buf,buf.length,new InetSocketAddress("127.0.0.1",8888));
// 创建数据报套接字并将其绑定到本地主机上的指定端口(client本身占据9999端口)。
DatagramSocket socket = new DatagramSocket(9999);
// 从此套接字发送数据报包。
socket.send(packet);
// 关闭此数据报套接字。
socket.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
iii.
运行结果:
先启动服务端,再启动客户端,现在用cmd端口来启动服务端与客户端。
服务端运行结果:
客户端运行结果:
学习TCP/IP协议推荐的书籍:
《TCP/IP详解》
——厚积薄发(yuanxw)