首先盲寫的一個傳輸文件的方法,但測試發現了一個非常不容易發現的問題,這裡先說明一下。
錯誤的代碼如下:
1 package com.TCP.java;
2
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.FileNotFoundException;
6 import java.io.FileOutputStream;
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.OutputStream;
10 import java.net.InetAddress;
11 import java.net.ServerSocket;
12 import java.net.Socket;
13
14 import org.junit.Test;
15
16 //從客戶端發送文件給服務端,服務端保存到本地。並返回“發送成功”給客戶端。並關閉相應的連接。
17 public class TestTCP3 {
18 //客戶端
19 @Test
20 public void client(){
21 Socket socket = null;
22 OutputStream os = null;
23 FileInputStream fis = null;
24 InputStream is = null;
25 try {
26 //創建一個Socket的對象
27 socket = new Socket(InetAddress.getByName("192.168.1.101"),9090);
28 //從本地獲取一個文件發送給服務端
29 os = socket.getOutputStream();
30 fis = new FileInputStream(new File("findLei.jpg"));
31 byte[] b = new byte[1024];
32 int length;
33 while((length = fis.read(b)) != -1){
34 os.write(b,0,length);
35 }
36 socket.shutdownOutput();
37 //接收來自服務端的信息
38 is = socket.getInputStream();
39 byte[] b1 = new byte[1024];
40 int length1;
41 while((length1 = is.read(b1)) != -1){
42 String str = new String(b1,0,length1);
43 System.out.println(str);
44 }
45 }catch (IOException e) {
46 e.printStackTrace();
47 }
48 finally{
49 //關閉相應的流和Socket對象
50 if(is != null){
51 try {
52 is.close();
53 } catch (IOException e) {
54 e.printStackTrace();
55 }
56 }
57 if(fis != null){
58 try {
59 fis.close();
60 } catch (IOException e) {
61 e.printStackTrace();
62 }
63 }
64 if(os != null){
65 try {
66 os.close();
67 } catch (IOException e) {
68 e.printStackTrace();
69 }
70 }
71 if(socket != null){
72 try {
73 socket.close();
74 } catch (IOException e) {
75 e.printStackTrace();
76 }
77 }
78 }
79 }
80
81 //服務端
82 @Test
83 public void server(){
84 ServerSocket ss = null;
85 Socket s = null;
86 InputStream is = null;
87 FileOutputStream fos = null;
88 OutputStream os = null;
89 try {
90 //創建一個ServerSocket的對象
91 ss = new ServerSocket(9090);
92 //調用accept()方法,返回一個Socket對象
93 s = ss.accept();
94 //將從客戶端發送的信息保存到本地
95 is = s.getInputStream();
96 fos = new FileOutputStream("D:/Test");
97 // Random random = new Random();
98 // fos = new FileOutputStream("D:/Test/" + String.valueOf(random.nextInt(90)) + ".jpg");
99 // fos = new FileOutputStream("find2.jpg");
100 byte[] b = new byte[1024];
101 int length;
102 while((length = is.read(b)) != -1){
103 fos.write(b, 0, length);
104 }
105 //發送接收成功的消息
106 os = s.getOutputStream();
107 os.write("接收成功".getBytes());
108 } catch (FileNotFoundException e) {
109 e.printStackTrace();
110 } catch (IOException e) {
111 e.printStackTrace();
112 }
113 finally{
114 //關閉相應的流及ServerSocket,Socket對象
115 if(os != null){
116 try {
117 os.close();
118 } catch (IOException e) {
119 e.printStackTrace();
120 }
121 }
122 if(fos != null){
123 try {
124 fos.close();
125 } catch (IOException e) {
126 e.printStackTrace();
127 }
128 }
129 if(is != null){
130 try {
131 is.close();
132 } catch (IOException e) {
133 e.printStackTrace();
134 }
135 }
136 if(s != null){
137 try {
138 s.close();
139 } catch (IOException e) {
140 e.printStackTrace();
141 }
142 }
143 if(ss != null){
144 try {
145 ss.close();
146 } catch (IOException e) {
147 e.printStackTrace();
148 }
149 }
150 }
151 }
152 }
有看出來問題麼,沒有,看著一點問題也沒有,但執行的時候就是報錯,而且報錯的位置著實很頭痛,在那附近找了很久也沒找到......
下面是所報Error的信息
1 java.net.SocketException: Software caused connection abort: socket write error 2 at java.net.SocketOutputStream.socketWrite0(Native Method) 3 at java.net.SocketOutputStream.socketWrite(Unknown Source) 4 at java.net.SocketOutputStream.write(Unknown Source) 5 at com.TCP.java.TestTCP3.client(TestTCP3.java:35) 6 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 7 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 8 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 9 at java.lang.reflect.Method.invoke(Unknown Source) 10 at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 11 at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 12 at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 13 at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 14 at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 15 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 16 at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 17 at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 18 at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 19 at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 20 at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 21 at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 22 at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 23 at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 24 at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 25 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 26 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) 27 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 28 at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
指定的位置是35行寫入的問題,但是找了很久也沒找到原因,還要感謝我大姚哥幫我找到了這個問題
先說明一下這個Error的意思,大概就是Socket在寫入的時候出現故障了,調查這段代碼的過程就不一一詳述了,就說一下真正的原因在哪,真正的原因是server端需要寫入的文件夾目錄有問題,我寫的是fos = new FileOutputStream("D:/Test");這個路徑在直接寫入文件的時候有問題,這裡進行復制的時候需要指定其格式,及其命名,這個路徑明顯缺少這兩樣,而如果改成相對路徑就沒有那麼麻煩了,fos = new FileOutputStream("find2.jpg");這樣執行就成功了,但如果我們想將文件放在指定目錄下呢,可以用這種方式
Random random = new Random();
fos = new FileOutputStream("D:/Test/" + String.valueOf(random.nextInt(90)) + ".jpg")
這種方式可以自動添加一個隨機數,使其避免了重命名的風險,反正問題是已經解決了,成功代碼只需打開注釋即可
下面說明一下此TCP傳輸需要進行的操作及實現的功能
1.選中server(服務端),用JUnit啟動。當傳輸文件時服務一定要先開啟啊,這是常識
2.選中client(客戶端),用JUnit啟動。其中這裡有兩個參數是需要手動改的,一個是IP,即你想要傳輸到的電腦(這台電腦要啟動server)的IP;另一個就是端口號,這個是自己隨便命名的,像Tomcat一樣也需要一個端口號(Tomcat是8080)。
3.成功復制文件並打印友好回饋
*4.第二天在同一局域網上的兩台機器上測試,竟然不好使,尚未未找到原因,看到這篇博客的希望給點兒建議~