一、网络基础(TCP/IP详解)
1、IP协议(Internet Protocol):网络层,支持网间数据报通信。无连接数据报传送,数据报路由选择和差错控制。
IPv4 32位(4字节),IPv6 128位(16字节)。P
ping ICMP协议
2、TCP协议、UDP协议
(1)TCP(transmission control protocol 打电话):专门设计用于在不可靠的因特网上提供可靠的、端到端的字节流通信的协议。它是一种面向连接的协议。有三次握手。慢
(2)UDP(user data protocol 寄信):提供了一种发送封装的原始IP数据报的方法、并且发送时无需建立连接,是一种不可靠的连接。快
二、Socket
两个Java应用程序可以通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称为一个Socket。
Socket通常用来实现client-server连接。
java.net包中定义的两个类Socket和ServerSocket,分别用来实现双向连接(TCP连接)的client和server端。
建立连接时所需的寻址信息为远程计算机的IP地址和端口号(Port number)。端口号2字节,可以区分不同的应用程序。端口号又分TCP端口和UDP端口,每个都是65536个端口。
例如:
收邮件 POP3 110
STMP 25
FTP 21
HTTP 80
1、TCP Socket通信模型
这只是练习,实际上的网络编程都是异步式的。System.in,accept(),readUTF()都是阻塞式的(非重点)
例1
import java.net.*; import java.io.*; public class TCPServer{public static void main(String args[]) throws Exception{ServerSocket ss = new ServerSocket(6666);//端口号6666while(true){Socket s = ss.accept();System.out.println("a client connect!");DataInputStream dis = new DataInputStream(s.getInputStream());System.out.println(dis.readUTF());dis.close();s.close();}} }
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);OutputStream os = s.getOutputStream();DataOutputStream dos = new DataOutputStream(os);dos.writeUTF("hello server!");dos.flush();dos.close();s.close();} }
例2
import java.io.*; import java.net.*; public class TestServer{public static void main(String[] args){try{ServerSocket s = new ServerSocket(8888);//服务器端口号8888while(true){Socket s1 = s.accept();OutputStream os = s1.getOutputStream();DataOutputStream dos = new DataOutputStream(os);dos.writeUTF("Hello,"+s1.getInetAddress()+"port#"+s1.getPort()+" byebye!");//客户端的IP地址和端口号 dos.close();s1.close();}}catch(IOException e){e.printStackTrace();}} }
import java.net.*; import java.io.*; public class TestClient{public static void main(String[] args){try{Socket s1 = new Socket("127.0.0.1",8888);//服务器地址和端口号InputStream is = s1.getInputStream();DataInputStream dis = new DataInputStream(is);System.out.println(dis.readUTF());dis.close();s1.close();}catch(ConnectException e){e.printStackTrace();}catch(IOException e){e.printStackTrace();}} }
例3
import java.io.*; import java.net.*; public class TestServer{public static void main(String[] args){InputStream in = null;OutputStream out = null;try{ServerSocket ss = new ServerSocket(5888);//设置端口号Socket s1 = ss.accept();in = s1.getInputStream();out = s1.getOutputStream();DataOutputStream dos = new DataOutputStream(out);DataInputStream dis = new DataInputStream(in);String s = null;if((s=dis.readUTF())!=null){System.out.println(s);System.out.println("from: "+s1.getInetAddress());System.out.println("Port: "+s1.getPort());}dos.writeUTF("hi,hello");dis.close();dos.close();s1.close();}catch(IOException e){e.printStackTrace();}} }
import java.net.*; import java.io.*; public class TestClient{public static void main(String[] args){InputStream in = null;OutputStream out = null;try{Socket s1 = new Socket("localhost",5888);//服务器地址和端口号in = s1.getInputStream();out = s1.getOutputStream();DataInputStream dis = new DataInputStream(in);DataOutputStream dos = new DataOutputStream(out);dos.writeUTF("hey");String s = null;if((s=dis.readUTF())!=null){System.out.println(s); }dos.close();dis.close();s1.close();}catch(UnknownHostException e){e.printStackTrace();}catch(IOException e){e.printStackTrace();}} }
练习4:(by myself)
import java.io.*; import java.net.*; public class TestServer{public static void main(String[] args){InputStream in = null;OutputStream out = null;String si = null;String so = "";try{ServerSocket ss = new ServerSocket(5888);//设置端口号while(true){Socket s1 = ss.accept();in = s1.getInputStream();//接收数据out = s1.getOutputStream();//发送数据DataInputStream dis = new DataInputStream(in);DataOutputStream dos = new DataOutputStream(out);//从键盘读入InputStreamReader isr2 = new InputStreamReader(System.in);BufferedReader br2 = new BufferedReader(isr2);while(!so.equals("exit")){if((so=br2.readLine())!=null&&!so.equals("exit")){System.out.println("Server:"+so);dos.writeUTF(so);}if((si=dis.readUTF())!=null){System.out.println("Client:"+si); } } dis.close();br2.close();dos.close();s1.close();}}catch(IOException e){e.printStackTrace();}} }
import java.net.*; import java.io.*; public class TestClient{public static void main(String[] args){InputStream in = null;OutputStream out = null;String si = null;String so= "";try{Socket s1 = new Socket("127.0.0.1",5888);//服务器地址和端口号in = s1.getInputStream();//接收out = s1.getOutputStream();//发送DataInputStream dis = new DataInputStream(in);DataOutputStream dos = new DataOutputStream(out);//从键盘读入InputStreamReader isr2 = new InputStreamReader(System.in);BufferedReader br2 = new BufferedReader(isr2); while(!so.equals("exit")){if((si=dis.readUTF())!=null){System.out.println("Server:"+si); } if((so=br2.readLine())!=null&&!so.equals("exit")){System.out.println("Client:"+so);dos.writeUTF(so);}} dis.close();br2.close();dos.close();s1.close();}catch(UnknownHostException e){e.printStackTrace();}catch(IOException e){e.printStackTrace();}} }
2、UDP Socket通信模型
没有server,client的概念,不区分两者的socket。receive()方法也是阻塞式的。
例1
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(5678);while(true){ds.receive(dp);System.out.println(new String(buf, 0, dp.getLength()));}} }
import java.net.*; public class TestUDPClient{public static void main(String args[]) throws Exception{byte[] buf = (new String("Hello")).getBytes();DatagramPacket dp = new DatagramPacket(buf, buf.length, new InetSocketAddress("127.0.0.1", 5678));DatagramSocket ds = new DatagramSocket(9999);ds.send(dp);ds.close();} }
例2
import java.net.*; import java.io.*; public class TestUDPServer{public static void main(String args[]) throws Exception{byte buf[] = new byte[1024];ByteArrayInputStream bais = new ByteArrayInputStream(buf);//从字节数组读数据DataInputStream dis = new DataInputStream(bais);DatagramPacket dp = new DatagramPacket(buf, buf.length);DatagramSocket ds = new DatagramSocket(5678);while(true){ds.receive(dp);long l = dis.readLong();System.out.println(l);}} }
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();} }