1. TCP和UDP协议介绍
UDP协议:
将数据及源和目的封装成数据包中,不需要建立连接
每个数据报的大小在限制在64k 内
因无连接,是不可靠协议
不需要建立连接,速度快
TCP协议:
建立连接,形成传输数据的通道。
在连接中进行大数据量传输
通过三次握手完成连接,是可靠协议
必须建立连接,效率会稍低
根据以上的传输条件和协议,可以为通信建立相应的客户端和服务器端。
三、代码实现
tcp:要求是在客户端输入信息,在服务器端输出,并在客户端打印服务端给的反馈信息
1. package cn.itcast.udp;
2.
3. import java.io.BufferedReader;
4. import java.io.IOException;
5. import java.io.InputStreamReader;
6. import java.net.DatagramPacket;
7. import java.net.DatagramSocket;
8. import java.net.InetAddress;
9.
10. /*
11. * 客户端:
12. * 通过键盘录入数据。"886"表示停止。
13. */
14. public class SendClient {
15. public static void main(String[] args) throws IOException {
16. // 创建UDP发送端的服务
17. DatagramSocket ds = new DatagramSocket();
18. // 把键盘录入数据用高效缓冲流封装
19. BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
20.
21. String line = null;
22. while ((line = br.readLine()) != null) {
23. if ("886".equals(line)) {
24. break;
25. }
26. byte[] bys = line.getBytes();
27. // 数据包
28. DatagramPacket dp = new DatagramPacket(bys, bys.length,
29. InetAddress.getByName("liuyi"), 11111);
30. // 发送数据
31. ds.send(dp);
32. }
33.
34. // 关闭资源
35. ds.close();
36. }
37.
38. }
39.
40. package cn.itcast.udp;
41.
42. import java.io.IOException;
43. import java.net.DatagramPacket;
44. import java.net.DatagramSocket;
45.
46. /*
47. * 服务端:
48. * 接受端一直开启服务。
49. */
50. public class ReceiveServer {
51. public static void main(String[] args) throws IOException {
52. // 创建UDP接收端Socket对象
53. DatagramSocket ds = new DatagramSocket(11111);
54.
55. // 为了循环多次接受
56. while (true) {
57. // 创建字节数组作为数据包的缓冲区
58. byte[] bys = new byte[1024];
59. DatagramPacket dp = new DatagramPacket(bys, bys.length);
60. // 读取数据包数据
61. ds.receive(dp);
62.
63. // 解析数据包
64. String ip = dp.getAddress().getHostAddress();
65. int port = dp.getPort();
66.
67. String text = new String(dp.getData(), 0, dp.getLength());
68. System.out.println(ip + "***" + port + "***" + text);
69. }
70.
71. // 关闭资源
72. // ds.close();
73. }
74.
75. }
package cn.itcast.udp;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*
* 客户端:
* 通过键盘录入数据。"886"表示停止。
*/
public class SendClient {
public static void main(String[] args) throws IOException {
// 创建UDP发送端的服务
DatagramSocket ds = new DatagramSocket();
// 把键盘录入数据用高效缓冲流封装
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = null;
while ((line = br.readLine()) != null) {
if ("886".equals(line)) {
break;
}
byte[] bys = line.getBytes();
// 数据包
DatagramPacket dp = new DatagramPacket(bys, bys.length,
InetAddress.getByName("liuyi"), 11111);
// 发送数据
ds.send(dp);
}
// 关闭资源
ds.close();
}
}
package cn.itcast.udp;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
/*
* 服务端:
* 接受端一直开启服务。
*/
public class ReceiveServer {
public static void main(String[] args) throws IOException {
// 创建UDP接收端Socket对象
DatagramSocket ds = new DatagramSocket(11111);
// 为了循环多次接受
while (true) {
// 创建字节数组作为数据包的缓冲区
byte[] bys = new byte[1024];
DatagramPacket dp = new DatagramPacket(bys, bys.length);
// 读取数据包数据
ds.receive(dp);
// 解析数据包
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String text = new String(dp.getData(), 0, dp.getLength());
System.out.println(ip + "***" + port + "***" + text);
}
// 关闭资源
// ds.close();
}
}
注意点:在运行代码时,可以先运行服务端也可以先运行客户端
tcp案例:在客户端上传文件,服务器端接收并存储文件,,
所以在这里,我模拟了多线程上传文件的情形。
1. //服务器端的线程
2. package cn.itcast.tcp;
3.
4. import java.io.BufferedReader;
5. import java.io.File;
6. import java.io.FileWriter;
7. import java.io.IOException;
8. import java.io.InputStreamReader;
9. import java.io.PrintWriter;
10. import java.net.Socket;
11.
12. public class UploadThraad implements Runnable {
13. //线程要共享的变量
14. private Socket s;
15. public UploadThraad(Socket s) {
16. this.s = s;
17. }
18. //将服务器端要执行的代码放到run方法内
19. @Override
20. public void run() {
21. // 获取IP
22. String ip = s.getInetAddress().getHostAddress();
23. System.out.println(ip + "连接上了");
24. try {
25.
26. File file = new File("d:\\java");
27. if (!file.exists()) {
28. file.mkdir();
29. }
30.
31. long time = System.currentTimeMillis();
32.
33. File fileDir = new File(file, ip +"-"+time + ".txt");
34.
35. // 从客户端获取输入写入到文件中,将文件流信息用包装流更高效
36. BufferedReader br = new BufferedReader(new InputStreamReader(
37. s.getInputStream()));
38.
39. PrintWriter pw = new PrintWriter(new FileWriter(fileDir), true);
40.
41. String line = null;
42. while ((line = br.readLine()) != null) {
43. pw.println(line);
44. }
45.
46. // 给客户端一个反馈
47. PrintWriter pwClient = new PrintWriter(s.getOutputStream(), true);
48. pwClient.println("上传成功了");
49.
50. pw.close();
51. s.close();
52. // ss.close();
53. } catch (IOException e) {
54. e.printStackTrace();
55. }
56. }
57. }
58.
59. //客户端的代码
60. package cn.itcast.tcp;
61.
62. import java.io.BufferedReader;
63. import java.io.FileReader;
64. import java.io.IOException;
65. import java.io.InputStreamReader;
66. import java.io.PrintWriter;
67. import java.net.Socket;
68.
69. /*
70. * 上传文件
71. */
72. public class UploadClient {
73. public static void main(String[] args) throws IOException {
74. Socket s = new Socket("192.168.1.100", 12021);
75.
76. // 把一个文本文件上传到服务器
77. BufferedReader br = new BufferedReader(new FileReader("hello.txt"));
78. PrintWriter pw = new PrintWriter(s.getOutputStream(), true);
79.
80. String line = null;
81. while ((line = br.readLine()) != null) {
82. pw.println(line);
83. }
84. //上传完毕后,就将流关闭,因为方法readLine是阻塞式的,否则会报错
85. s.shutdownOutput();
86.
87.
88. // 如果服务器接收到所有的数据后,给我一个反馈
89. BufferedReader serverBr = new BufferedReader(new InputStreamReader(
90. s.getInputStream()));
91. String text = serverBr.readLine();
92. System.out.println("server:" + text);
93.
94. br.close();
95. s.close();
96.
97. }
98.
99. }
100.
101. //测试类
102. package cn.itcast.tcp;
103.
104. import java.io.IOException;
105. import java.net.ServerSocket;
106. import java.net.Socket;
107.
108. public class UploadThreadTest {
109.
110. public static void main(String[] args) throws IOException {
111. ServerSocket ss = new ServerSocket(12021);
112.
113. while (true) {
114. Socket s = ss.accept();
115. new Thread(new UploadThraad(s)).start();
116. }
117. }
118.
119. }