09 JAVA 网络编程
2016-06-19 18:51
453 查看
一、概念
1. 计算机网络:计算机+外围设备+链路-》分享资源和信息处理等
2. 网络通信协议:不同的计算机不同的底层结构,网络通信协议相当于一系列标准,就像来自不同官方语言国家的两个人可以采用同一种语言进行沟通
3. 网络通信接口:
- 硬件装置,实现节点之间的信息传递,如网卡
- 软件装置,规定双方进行通信的约定协议
4. 分层:互不影响,灵活,利于拓展和实现
5. OSI参考模型 VS TCP/IP参考模型
01010...->帧frame->包packet->segment
- 应用层
- 表示层
- 会话层
- 传输层
- 网络层
- 数据链路层
- 物理层
6. IP是网际层的主要协议:
- 提供独一无二的IP地址
- 无连接数据报传送
- 数据报路由选择和差错控制
- 网络地址+主机地址(使用子网掩码来划分,如255.255.255.0)
**1
7. NAT:共享互联网,私网使用的是保留地址,而连接外网的接口使用的是非保留IP地址
- 私网IP
8. 网关gateway:内网,外围,两块内存
9. 广播:
- 直接广播,网络ID+主机ID(全1),像某个网段广播信息
- 本地广播,网络ID(全是1)+主机ID(全是1),像本地网段广播信息
10. 组播:广播给一组计算机
11. 划分子网例子:
http://blog.chinaunix.net/uid-20788636-id-1841323.html
12. TCP VS UDP:
TCP提供可靠地(但是慢,时效低),端到端的字节流通信的协议,是一种面向连接的协议,TCP连接是字节流而非报文,采用3次握手和重传(时间,重传次数,重复)
- A请求连接-》B
- A《- B接受请求,准备接收
- A -》B发送数据
- A《- B确认
UDP提供了一种发送封装的原始IP数据报的方法,发送之前不需建立连接,因此这是个不可靠的连接(但是速度快)
二、实现
java.net.Socket(插座):
双向的网络通信实现数据的交换,这个双向链路的一端称为socket,分别用来实现双向连接的client和server,建立连接时所需的寻址信息为远程计算机IP地址和端口号port number(TCP和UDP各有6万多个,一个应用程序可以有多个端口号,1024以下不要用,因为系统可能已经占用了)。对于UDP没有严格的client和server概念。
注意要先启动Server再启动Client,因为Server一般是不断的提供服务(同时打开多次同一个server是不可以的,accept方法是一个循环之后再执行另一个循环),所以我们可以while(true) {s.accept();},多个client可以同时申请连接,但是由服务器决定接收哪个连接。
- socket.getInetAddress() //获取客户端地址(超集,不一定是IP地址)
- socket.getPort()
多客户端Knock Knock游戏:
Reference:
1. http://blog.csdn.net/youxin2012/article/details/25778255
1. 计算机网络:计算机+外围设备+链路-》分享资源和信息处理等
2. 网络通信协议:不同的计算机不同的底层结构,网络通信协议相当于一系列标准,就像来自不同官方语言国家的两个人可以采用同一种语言进行沟通
3. 网络通信接口:
- 硬件装置,实现节点之间的信息传递,如网卡
- 软件装置,规定双方进行通信的约定协议
4. 分层:互不影响,灵活,利于拓展和实现
5. OSI参考模型 VS TCP/IP参考模型
01010...->帧frame->包packet->segment
- 应用层
- 表示层
- 会话层
- 传输层
- 网络层
- 数据链路层
- 物理层
6. IP是网际层的主要协议:
- 提供独一无二的IP地址
- 无连接数据报传送
- 数据报路由选择和差错控制
- 网络地址+主机地址(使用子网掩码来划分,如255.255.255.0)
**1
IP地址分类 | 第一字节范围 | 固定最高位 | 网络位 | 网络数 | 主机位 | 主机数 |
A | 0~127 | 0 | 8 | 126 (0和127特殊用途) | 16777214 (2^24 - 2) | |
B | 128~191 | 10 | 16 | 2^14 | 16 | 2^16 -2 |
C | 192~223 | 110 | 24 | 2^21 | 8 | 2^8 -2 |
D | 224~239 | 1110 | 组播地址 | |||
E | 240~255 | 11110 | 保留给实验用 |
特殊地址 | 网络id | 主机id | 源地址使用 | 目的地址使用 | 备注 |
本网络的本台主机 | 全0 | 全0 | 可以 | 不可以 | 运行引导程序时,但又不知道其ip, 则使用这个 |
本网络的某台主机 | 全0 | 主机id | 不可以 | 可以 | |
网络地址 | 网络id | 全0 | 可以 | 可以 | |
直接广播地址 | 网络id | 全1 | 不可以 | 可以 | 特定网络所有主机,即全网广播 |
受限/本地 广播地址 | 全1 | 全1 | 不可以 | 可以 | |
回送地址 | 127 | 任何数 | 可以 | 可以 |
- 私网IP
类型 | 网络地址 | 网络数 |
A | 10.x.x.x | 1 |
B | 172.16.x.x ~ 172.31.x.x | 16 |
C | 192.168.x.x ~ 192.168.x.x | 256 |
9. 广播:
- 直接广播,网络ID+主机ID(全1),像某个网段广播信息
- 本地广播,网络ID(全是1)+主机ID(全是1),像本地网段广播信息
10. 组播:广播给一组计算机
11. 划分子网例子:
http://blog.chinaunix.net/uid-20788636-id-1841323.html
12. TCP VS UDP:
TCP提供可靠地(但是慢,时效低),端到端的字节流通信的协议,是一种面向连接的协议,TCP连接是字节流而非报文,采用3次握手和重传(时间,重传次数,重复)
- A请求连接-》B
- A《- B接受请求,准备接收
- A -》B发送数据
- A《- B确认
UDP提供了一种发送封装的原始IP数据报的方法,发送之前不需建立连接,因此这是个不可靠的连接(但是速度快)
二、实现
java.net.Socket(插座):
双向的网络通信实现数据的交换,这个双向链路的一端称为socket,分别用来实现双向连接的client和server,建立连接时所需的寻址信息为远程计算机IP地址和端口号port number(TCP和UDP各有6万多个,一个应用程序可以有多个端口号,1024以下不要用,因为系统可能已经占用了)。对于UDP没有严格的client和server概念。
注意要先启动Server再启动Client,因为Server一般是不断的提供服务(同时打开多次同一个server是不可以的,accept方法是一个循环之后再执行另一个循环),所以我们可以while(true) {s.accept();},多个client可以同时申请连接,但是由服务器决定接收哪个连接。
- socket.getInetAddress() //获取客户端地址(超集,不一定是IP地址)
- socket.getPort()
import java.net.*; import java.io.*; 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(5678); while(true) { ds.receive(dp); ByteArrayInputStream bais = new ByteArrayInputStream(buf); DataInputStream dis = new DataInputStream(bais); 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(); System.out.println(buf.length); DatagramPacket dp = new DatagramPacket(buf, buf.length, new InetSocketAddress("127.0.0.1", 5678) ); DatagramSocket ds = new DatagramSocket(9999); ds.send(dp); ds.close(); } }
多客户端Knock Knock游戏:
import java.net.*; import java.io.*; public class KKThread extends Thread{ Socket s = null; KKThread(Socket s) { super("MultiServerThread"); this.s = s; } public void run() { try(BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); PrintWriter pw = new PrintWriter(new OutputStreamWriter(s.getOutputStream()))) { KKState kks = new KKState(); String input, output; output = kks.processInput(null); pw.println(output); pw.flush(); while((input = br.readLine()) != null) { output = kks.processInput(input); pw.println(output); pw.flush(); if(output.equals("Bye")) break; } br.close(); pw.close(); s.close(); } catch(IOException e) { e.printStackTrace(); } } } public class KKState { private static final int WAITING = 0; private static final int SENTKNOCK = 1; private static final int SENTCLUE = 2; private static final int ANOTHER = 3; private static final int NUMOFJOKES = 5; private int current = 0; private int state = WAITING; private final String[] clues = {"Turnip", "Little Old Lady", "Atch", "Who", "Who"}; private final String[] ans = {"Turnip the heat, It's cold in there.", "I didn't know you could yodel.", "Bless you.", "Is there an owl in there.", "Is there an echo in there."}; String processInput(String input) { String output = null; if(state == WAITING) { output = "Knock Knock"; state = SENTKNOCK; } else if(state == SENTKNOCK) { if(input.equalsIgnoreCase("Who's there?")) { output = clues[current]; state = SENTCLUE; } else { output = "You are supposed to say \"Who's there?\"!Try again. Knock Knock"; } } else if(state == SENTCLUE) { if(input.equalsIgnoreCase(clues[current]+" who?")) { output = ans[current] + " Want another[y/n]"; state = ANOTHER; } else { output = "You are supposed to say \""+clues[current]+" who?\"!Try again. Knock Knock"; state = SENTKNOCK; } } else if(state == ANOTHER) { if(input.equalsIgnoreCase("y")) { output = "KNOCK KNOCK"; if(current == (NUMOFJOKES - 1)) { current = 0; } else current++; state = SENTKNOCK; } else { output = "Bye"; state = WAITING; } } return output; } } import java.net.*; import java.io.*; public class KnokServer { public static void main(String[] args) { try(ServerSocket ss = new ServerSocket(9998)) { System.out.println("Server started"); while(true) { Socket cs = null; try { cs = ss.accept(); } catch(IOException e) { System.out.println("Accept failed: " + 9998 + "," +e.getMessage()); continue; } new KKThread(cs).start(); } } catch(IOException e) { System.err.println("Could not listen on port: " + 9998 + "," + e.getMessage()); } } } import java.net.*; import java.io.*; public class KKClient { public static void main(String[] args) { try(Socket cs = new Socket("127.0.0.1", 9998)) { try { PrintWriter pw = new PrintWriter(new OutputStreamWriter(cs.getOutputStream())); BufferedReader br = new BufferedReader(new InputStreamReader(cs.getInputStream())); String input, output; try { while((input = br.readLine()) != null) { System.out.println("Server: " + input); if(input.equals("Bye")) { break; } BufferedReader sin = new BufferedReader(new InputStreamReader(System.in)); output = sin.readLine(); System.out.println("Client: " + output); pw.println(output); pw.flush(); } } catch(IOException e) { System.err.println("Unable to open I/0 streams " + e); } pw.close(); br.close(); } catch(IOException e) { System.err.println("Unable to open socket to Host " + e); } cs.close(); } catch(IOException e) { System.err.println("Unable to connect the host" + e); } } }
Reference:
1. http://blog.csdn.net/youxin2012/article/details/25778255
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树