一、网络基础概念
▶什么是计算机网络:
把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息,共享硬件、软件、数据信息等资源。
二、网络协议分层的思想
▶为什么要分层?
由于结点之间联系很复杂,在制订协议时,把复杂成分分解成一些简单的成分,再将他们复合起来。
最常用的复合方式是层次方式,即同层间可以通信,上一层可以调用下一层,而与再下一层不发生关系。各层互不影响,有利于系统的开发和扩展。
▶通信协议的分层规定
把用户应用程序作为最高层,把物理通信线路作为最低处,将其间的协议处理分为若干层,规定每层处理的任务,也规定每层的接口标准。
参考模型
三、TCP 协议和UDP协议
▶TCP(transmission control protocol)
是专门设计用于在不可靠的因特网上提供可靠的、端到端的字节流通信的协议。它是一种面向连接的协议。TCP连接是字节流而非报文流。
▶UDP(user data protocol)
UDP向应用程序提供了一种发送封装的原始IP数据报的方法、并且发送时无需建立连接。是一种不可靠的连接。
四、Socket
▶两个Java应用程序可以通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket。
▶Socket通常用来实现client-server 连接。
▶java.net 包中定义的两个类Socket 和 ServerSocket ,分别用来实现双向连接的 client 和server 端。
▶建立连接时所需的寻址信息为远程计算机的IP地址 和 端口号(Port number)。
▼端口又分 TCP 端口和 UDP 端口,每个有65536个
例1:TCPServer.java、TCPClient.java
import java.net.*;
import java.io.*;
public class TCPServer {
public static void main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(6666);//指定一个端口。阻塞式,等待连接
while(true) {
Socket s = ss.accept();
DataInputStream dis = new DataInputStream(s.getInputStream());
System.out.println(dis.readUTF());//阻塞式
dis.close();
s.close();
System.out.println("A client connect!");
}
}
}
import java.net.*;
import java.io.*;
public class TCPClient {
public static void main(String[] args) throws Exception {
Socket s = new Socket("127.0.0.1",6666);//回送地址。Client的端口系统随机选择。
OutputStream os = s.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF("hello Server!");
dos.flush();
dos.close();
s.close();
}
}
例2:TestSockServer.java, TestSockClient.java (不能同时读,同时写。)
import java.net.*;
import java.io.*;
public class TestSockServer {
public static void main(String[] args){
OutputStream out = null;
InputStream in = null;
try {
ServerSocket ss = new ServerSocket(5888);
while(true) {
Socket s = ss.accept();
in = s.getInputStream();
out = s.getOutputStream();
DataInputStream dis = new DataInputStream(in);
DataOutputStream dos = new DataOutputStream(out);
String str = null;
if((str=dis.readUTF())!=null) {
System.out.println(str);
System.out.println("from: "+s.getInetAddress());
System.out.println("port: "+s.getPort());
}
dos.writeUTF("hi,hello!");
dis.close();
dos.close();
s.close();
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
import java.net.*;
import java.io.*;
public class TestSockClient {
public static void main(String[] args){
OutputStream os = null;
InputStream is = null;
try {
Socket s = new Socket("127.0.0.1",5888);
is = s.getInputStream();
os = s.getOutputStream();
DataInputStream dis = new DataInputStream(is);
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF("hey");
String str = null;
if((str=dis.readUTF())!=null) {
System.out.println(str);
}
dos.close();
dis.close();
s.close();
}catch(ConnectException e1) {
e1.printStackTrace();
System.out.println("连接出错");
}catch(IOException e2) {
e2.printStackTrace();
}
}
}
例3:TestUDPServer.java、TestUDPClient.java
import java.io.*;
import java.net.*;
public class TestUDPServer {
public static void main(String[] args) throws Exception {
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
DatagramSocket ds = new DatagramSocket(8888);
while(true) {
ds.receive(dp);//收到东西就收到dp
ByteArrayInputStream bis = new ByteArrayInputStream(buf);
DataInputStream dis = new DataInputStream(bis);
System.out.println(dis.readLong());
}
}
}
import java.net.*;
import java.io.*;
public class TestUDPClient {
public static void main(String[] args) throws Exception {
long n = 10000L;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
dos.writeLong(n);
byte[] buf = baos.toByteArray();
DatagramPacket dp = new DatagramPacket(buf,buf.length,new InetSocketAddress("127.0.0.1",8888));
DatagramSocket ds = new DatagramSocket(9999);
ds.send(dp);
ds.close();
}
}