首先我们了解一下什么是网络:
•用一种中间的介质(电线、双绞线、蓝牙)实现资源共享和通信
• 连接终端系统(电脑、手机、卫星等等)的通信系统
ISO(International Standard Organized )制定的OSI参考模型(Open System Interconnection)
OSI模型分为七层,第1、2层解决网络怎么连的问题 ,第3层解决网络怎么找 ,第4层解决网络怎么传,第 5、6、7解决网络传什么,如下图所示。
然后我们来了解一下网络编程经常出现的一些名词
• IP 地址:连接至网络的每台计算机都是唯一的32 位数字,四个用点号分隔的数包括网络 ID 和主机 ID。例如“127.0.0.01”网络的类包括 A、B、C和 D 类 • 域名系统
• DNS
域名系统将特定 IP 地址映射至字符串,映射由域名服务器系统维护
•端口:用于实现程序间的通信
•传输协议网络中计算机之间的通讯规则
•客户端向另一台计算机请求服务的终端
•服务器处理客户端请求的计算机
然后我们来看一个基于TCP(双向的稳定的不间断的数据流)通讯的例子,完成的是客户端和服务器之间的通讯,直到客户端发来再见才能停止通讯。(有点类似于你跟10086打电话,你是客户端,10086是服务器)
这是服务器的代码,值得注意的是,运行程序的时候必须先运行服务器端的代码
public static void main(String[] args) {
System.out.println("服务器启动!");
ServerSocket serverSocket = null;
Socket socket = null;
BufferedWriter writer = null;
BufferedReader reader = null;
try {
serverSocket = new ServerSocket(10099);
socket = serverSocket.accept();
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String info = null;
while(true) {
info = reader.readLine();
System.out.println("服务器收到的消息是:" + info);
if("再见".equals(info)) {
break;
}
}
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write("啦啦啦\n");
writer.flush();
writer.write("再见\n");
writer.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
if(socket != null) {
socket.close();
System.out.println(socket.isClosed() +" 1");
}if(serverSocket != null) {
serverSocket.close();
System.out.println(serverSocket.isClosed() + " 2");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
这是客户端的代码
public static void main(String[] args) {
System.out.println("客户端启动!");
Socket socket = null;
BufferedReader reader = null;
BufferedWriter writer = null;
try {
socket = new Socket("127.0.0.1", 10099);
writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
writer.write("啦啦啦\n");
writer.flush();
writer.write("再见\n");
writer.flush();
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String info = null;
while(true) {
info = reader.readLine();
System.out.println("客户端收到的消息是:" + info);
if("再见".equals(info)) {
break;
}
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
if(socket != null) {
socket.close();
System.out.println(socket.isClosed());
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
然后我们再看一个基于UDP(单向的不稳定的间断的数据包)的通讯,UDP1 发消息给UDP2 。这个例子两个类没有运行的先后顺序,如果先运行发邮件的类,顶多邮件不能发送到收件人手上,是不是很像发短信?
public class UDP1 {
public static void main(String[] args) {
DatagramPacket packet = null;
DatagramSocket socket = null;
byte [] pool = new byte[1024];
packet = new DatagramPacket(pool,0, pool.length);
try {
socket = new DatagramSocket(10088); //socket 类似于邮包 发出去端口号系统分配
socket.receive(packet); //packet有发邮件的方法
String info = new String(packet.getData());
System.out.println("UDP1收到的消息是:"+ info);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class UDP2 {
public static void main(String[] args) {
DatagramPacket packet = null;
DatagramSocket socket = null;
try {
byte[] pool = new byte[1024];
packet =new DatagramPacket(pool, 0, pool.length,InetAddress.getByName("127.0.0.1"), 10088);
socket = new DatagramSocket();
packet.setData("我是UDP2".getBytes());
socket.send(packet);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
注意的是进行通讯的时候,很多同学分不清消息的源头和目的地分别是什么,一定要保持脑袋清楚,不然会出现很大的问题。