09 JAVA 网络编程

一、概念

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任何数可以可以 

7. NAT:共享互联网,私网使用的是保留地址,而连接外网的接口使用的是非保留IP地址

- 私网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

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()

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值