java中网络编程
TCP/IP协议的四层模型,从底层到高层分别是:网络接口层、网络层、传输层、应用层。IP属于网络层,TCP/UDP属于传输层。IP定位对方的主机名,端口号对应接受数据的应用程序。
本地回环地址:127.0.0.1 主机名:localhost 有效端口:0~65535, 其中0~1024为系统保留端口。
IP地址由InetAddress类表示。没有构造函数,通过静态方法得到实例。
UDP:将数据及源和目的封装成数据包,不需要建立连接;每个数据包的大小限制在64k内;因无连接,是不可靠协议;速度快。
TCP:建立连接,形成传输数据的通道;在连接中进行大量数据传输;通过三次握手完成连接,是可靠协议;必须建立连接,效率稍低。
Socket:网络之间的通信其实就是Socket之间的通信,Socket之间通过IO进行传输。
DatagramSocket:UDP使用的Socket接口,是本地的接口;发送、接受的单位为DatagramPacket。注意:这里DatagramPacket里面有get/setPort的操作,其中set为设置此包的目的端口号,而get有两种情况,一种是未发送的时候得到刚才set的端口号,一种是在接收端得到发送端的Socket的端口号(发送端DatagramePacket的设置的端口号)。所以getPort是Packet的得到Port的方法,而getLocalPort是Socket得到Port的方法。
测试UDP传输简单的数据:
1 package net;
2 import java.net.DatagramPacket;
3 import java.net.DatagramSocket;
4 import java.net.InetAddress;
5 //主线程为server端接受,子线程为client发送
6 public class TestUDP {
7 public static void main(String[] args) {
8 // TODO Auto-generated method stub
9 UDPClient udpClient = new UDPClient();
10 Thread t1 = new Thread(udpClient);
11 t1.start();
12 UDPServerFunc();
13 }
14 static void UDPServerFunc(){
15 try {
16 DatagramSocket dsServer = new DatagramSocket(7777);
17 System.out.println("Server DatagramSocket Port"+dsServer.getLocalPort());
18 byte[] buf = new byte[1024];
19 DatagramPacket dpServer = new DatagramPacket(buf, 0, buf.length);
20 dsServer.receive(dpServer);
21 System.out.println(dpServer.getAddress().getHostAddress() + " :: "
22 + new String(dpServer.getData(),0,dpServer.getLength()));
23 System.out.println("Server DatagramPacket Port"+dpServer.getPort());
24 } catch (Exception e) {
25 e.printStackTrace();
26 }
27 }
28 }
29 class UDPClient implements Runnable{
30 @Override
31 public void run() {
32 try {
33 DatagramSocket dsClient = new DatagramSocket(6666);
34 System.out.println("Client DatagramSocket Port"+dsClient.getLocalPort());
35 byte[] buf = "hello this is UDPTest".getBytes();
36 DatagramPacket dpClient =
37 new DatagramPacket(buf, buf.length,InetAddress.getByName("localhost"), 7777);
38 Thread.sleep(1000);
39 System.out.println("Client : "+"wakeup");
40 System.out.println("Client DatagramPacket Port"+dpClient.getPort());
41 dsClient.send(dpClient);
42 } catch (Exception e) {
43 e.printStackTrace();
44 }
45 }
46 }
UDP是没有“方向”的,所以用DatagramePacket既发送数据,又接收数据。但是TCP是有“方向”的连接,因此用两个类Socket 、ServerSocket分别表示客户端和服务器端, TCP先形成Socket的“通路”,然后再通过IO流在这条通路上进行数据的传输。即ServerSocket先接收到客户端的Socket,然后调用此Socket中的IO流实现数据的流传输。
1 package net;
2 //主进程中为server 子进程中为client
3 import java.io.BufferedReader;
4 import java.io.BufferedWriter;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.InputStreamReader;
8 import java.io.OutputStream;
9 import java.io.OutputStreamWriter;
10 import java.net.BindException;
11 import java.net.ServerSocket;
12 import java.net.Socket;
13 import java.net.UnknownHostException;
14
15 public class TestTCP {
16 public static void main(String[] args){
17 try {
18 ServerSocket ssever = new ServerSocket(7777);
19 System.out.println("ServerSocket Port:" + ssever.getLocalPort());
20 Thread tclient = new Thread(new TCPClient());
21 tclient.start();
22
23 Socket s1 = ssever.accept();
24 InputStream serverIn = s1.getInputStream();
25 OutputStream serverOut = s1.getOutputStream();
26 System.out.println("Server : "+"connected host : "+"addr --"+s1.getInetAddress().getHostAddress()
27 +";port --"+s1.getPort());
28 BufferedReader serverBR = new BufferedReader(new InputStreamReader(serverIn));
29 BufferedWriter serverBW = new BufferedWriter(new OutputStreamWriter(serverOut));
30 System.out.println("ready");
31 // String serverStr ="aaaaaaaa";//测试数据用
32 String serverStr = serverBR.readLine();
33 while (true) {
34 if (serverStr.equalsIgnoreCase("over")) {
35 s1.close();
36 break;
37 }
38 System.out.println("Server receive string : " +serverStr);
39 Thread.sleep(500);
40 serverBW.write(serverStr.toUpperCase());
41 serverBW.newLine();
42 serverBW.flush();
43 serverStr = serverBR.readLine();
44 }
45
46 } catch (Exception e) {
47 System.out.println("main problem");
48 }
49 }
50 }
51 class TCPClient implements Runnable {
52 @Override
53 public void run() {
54 try {
55 Thread.sleep(1000);
56 Socket sclient = new Socket("localhost", 7777);
57 System.out.println("Client Socket Port"+sclient.getLocalPort());
58 BufferedReader consleBR = new BufferedReader(new InputStreamReader(System.in));
59 BufferedWriter clientBW = new BufferedWriter(new OutputStreamWriter(sclient.getOutputStream()));
60 BufferedReader clientBR = new BufferedReader(new InputStreamReader(sclient.getInputStream()));
61
62 String consoleStr = consleBR.readLine();
63 String receiveStr = null;
64 while(true){
65 if (consoleStr.equalsIgnoreCase("Over")) {
66 clientBW.write("over");
67 clientBW.newLine();
68 clientBW.flush();
69 break;
70 }
71 clientBW.write(consoleStr);
72 clientBW.newLine();
73 clientBW.flush();
74 // SOP.sop("console : "+consoleStr);
75 receiveStr = clientBR.readLine();
76 System.out.println("Client receive string : "+receiveStr);
77 consoleStr = consleBR.readLine();
78 }
79 clientBR.close();
80 clientBW.close();
81 consleBR.close();
82
83 } catch (UnknownHostException e) {
84 System.out.println("UnknownHostException ...");
85 } catch (InterruptedException e1) {
86 System.out.println("InterruptedException ...");
87 }catch (BindException e2) {
88 System.out.println("BindException ...");
89 }catch (IOException e) {
90 System.out.println("IOEcxeption ... ");
91 }
92 }
93
94 }