著名的OSI(Open System Interconnection,开放系统互联)七层模型定义了网络通信基础。
物理层:有关传输介质的特性标准。
数据链路层:定义单个链路上如何传输数据,如ATM,FDDI。
网络层: 定义端到端的包传输,所有节点的逻辑地址,路由实现的方式和学习的方式。如何 分包。IP,IPX.
传输层: 差错恢复协议或无差错恢复协议,同一主机上数据流输入复用,重新排序收到的数据包。TCP,UDP,SPX.
会话层:定义如何开始,控制和结束一个对话。RPC,SQL等。
表示层:定义数据格式及加密。
应用层:与其他计算机进行通信的应用,Telnet,HTTP,FTP,NFS,SMTP.
Java 从传输层开始向程序员提供编程接口。
TCP基础
TCP协议下的Socket称为有连接的Socket。
这种模式下的Socket必须在发送数据之前与目的地的Socket取得一个连接。建立后可以使用一个数据流接口,按照"打开-读-写-关闭"的顺序操作。
服务器端:
分配端口,端口总共有0-65535个。前1024已经被TCP/IP保留。
常用的API
ServerSocket,Socket。
最常用的3个方法:
ServerSocket.accept(); //产生“阻塞”
Socket.getInputStream(); //获得网络输入“管道”
Socket.getOutputStream(); //获得网络输出“管道”
例子:
简单的多线程TCP服务器。
mport java.net.ServerSocket;
import java.net.Socket;
/**
* 主程序监听指定端口的连接请求,如果接入一个客户端,则启动一个EchoServer子线程。
* @author wakin
*
*/
public class MainEchoServer {
/**
* @param args
*/
public static void main(String[] args) {
try {
ServerSocket sercerSocket = new ServerSocket(9999);
System.out.println("EchoServer在9999端口上监听...");
while(true) {
Socket socket = sercerSocket.accept();
System.out.println("建立一个新的连接...");
new EchoServer(socket).start(); //启动线程的第一种方法(见API文档),调用线程的run方法。
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Calendar;
public class EchoServer extends Thread{
private Socket socket =null;
public EchoServer(Socket s){
this.socket = s;
}
public void run() {
BufferedReader in = null;
PrintWriter out = null;
Calendar c = Calendar.getInstance();
String msg = null;
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(),true);
do {
msg = null;
msg = in.readLine();
if(msg == null){
System.out.println("通讯终止...");
break;
}
msg = msg.toUpperCase();
System.out.println("收到命令:"+msg);
if(msg.equals("DOW")){
switch(c.get(Calendar.DAY_OF_WEEK)){
case Calendar.SUNDAY : out.println("今天是SUNDAY");
break;
case Calendar.MONDAY : out.println("今天是MONDAY");
break;
case Calendar.TUESDAY: out.println("今天是TUESDAY");
break;
case Calendar.WEDNESDAY: out.println("今天是WEDNESDAY");
break;
case Calendar.THURSDAY: out.println("今天是THURSDAY");
break;
case Calendar.FRIDAY : out.println("今天是FRIDAY");
break;
case Calendar.SATURDAY: out.println("今天是SATURDAY");
break;
}
}
else if(msg.equals("DOY")){
out.println("今天是一年的第 "+c.get(Calendar.DAY_OF_YEAR)+"天");
}
else if(msg.startsWith("FREE")){
out.println("答复:"+msg.substring(5));
}
else if(msg!=null) {
out.println("无效的命令!");
}
} while (true);
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
System.out.println("关闭一个连接...");
if(in!=null)
in.close();
if(out!=null)
out.close();
if(this.socket!=null)
this.socket.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class EchoClient {
public static void main(String [] args) {
Socket socket = null;
BufferedReader in = null;
BufferedReader clientIn = null;
PrintWriter out = null;
try {
String msg = null;
socket = new Socket("localhost",9999);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
clientIn = new BufferedReader(new InputStreamReader(System.in));
out = new PrintWriter(socket.getOutputStream(),true);
while(true) {
msg = clientIn.readLine();
if(msg==null){
break;
}
else {
out.println(msg);
System.out.println(in.readLine());
}
}
System.out.println("关闭通讯...");
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
if(in!=null)
in.close();
if(out!=null)
out.close();
if(socket!=null)
socket.close();
} catch (Exception e2) {
e2.printStackTrace();
}
}
}
}