首页 > 技术文章 > java网络编程之TCP通讯

fuck1 2016-04-25 14:53 原文

java中的网络编程之TCP协议的详细介绍,以及如何使用,同时我在下面举2例说明如何搭配IO流进行操作,

 1 /*
 2  *TCP
 3  *建立连接,形成传输数据的通道;
 4  *在连接中进行大数据量传输;
 5  *通过三次握手完成连接,是可靠协议;
 6  *必须建立连接,效率会稍低 
 7  */
 8 
 9 /*
10  * TCP传输
11  * Socket和ServerSocket建立客户端和服务器端建立连接后,
12  * 通过Socket中的IO流进行数据的传输关闭socket同样,
13  * 客户端与服务器端是两个独立的应用程序。
14  */
15 
16 //-------------------------------
17 //下面的是TCP协议的服务器端代码
18 
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.net.ServerSocket;
22 import java.net.Socket;
23 
24 /*
25  * TCP协议接收数据
26  *     1.创建接收端的socket对象
27  *     2.监听客户端,返回一个对应的socket对象
28  *     3.获取输入流,读取数据,显示在控制台
29  *     4.释放资源
30  */
31 public class ServerDemo {
32     public static void main(String[] args) throws IOException {
33         // 创建接收端socket对象
34         ServerSocket ss = new ServerSocket(10086);
35 
36         // 监听客户端,返回一个对应的socket对象
37         // public Socket accept() 侦听并接受到此套接字的连接。
38         Socket s = ss.accept(); // 阻塞式方法,直到通道建立
39 
40         // 获取输入流,读取数据
41         InputStream is = s.getInputStream();
42         byte[] bys = new byte[1024];
43         int len = is.read(bys); // 阻塞式方法,直到数据发过来。
44         String ip = s.getInetAddress().getHostAddress();
45         
46         String str = new String(bys, 0, len);
47         System.out.println(str);
48 
49         // 释放资源
50         s.close();
51         ss.close(); // 这个不应该关闭
52     }
53 }
54 
55 //-------------------------------
56 //下面是客户端TCP协议的代码
57 import java.io.IOException;
58 import java.io.OutputStream;
59 import java.net.Socket;
60 
61 /*
62  *TCP协议发送数据:
63  *    1.创建发送端socket对象
64  *        这一步如果成功,就说明链接已经成功了。
65  *    2.获取输出流,写数据
66  *    3.释放资源 
67  *
68  *TCP一些服务器必须先开启,保证通道简历,否则直接报错。
69  *java.net.ConnectException: Connection refused: connect
70  */
71 public class ClientDemo {
72     public static void main(String[] args) throws IOException {
73         // 创建发送端socket对象
74         // Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号。
75         Socket socket = new Socket("lpp-PC", 10086); 
76 //“lpp-PC”里面的字符串一般使用服务器端的IP地址代替。
77 
78         // 获取输出流,写数据
79         OutputStream os = socket.getOutputStream();
80         os.write("TCP coming~~~".getBytes());
81 
82         // 关闭资源
83         os.close();
84     }
85 }
  1 //==================================
  2 //---------------------------------------------------------------
  3 //下面给出一个案例:客户端从指定文本文件读取数据,发送到服务器端,
  4 //服务器将接收到的数据,再次写入到一个新的文本文件。数据的写/出是字节
  5 //  6 
  7 //首先给出的是客户端的代码:
  8 import java.io.BufferedReader;
  9 import java.io.BufferedWriter;
 10 import java.io.FileReader;
 11 import java.io.IOException;
 12 import java.io.InputStreamReader;
 13 import java.io.OutputStreamWriter;
 14 import java.net.Socket;
 15 
 16 /*
 17  * 客户端从文本文件中读取数据,服务器得到数据写入到文本文件,
 18  * 为了在服务器写完数据后,给客户端一个反馈,但是直接在通道内额外的添加数据是不行,会导致双方一直保持等待状态
 19  *     方案  
 20  *       1:  在客户端里面额外增加一条语句告诉服务器结束的标志。
 21  *       2: 直接使用JDK给出的方法:shutdownOutput();socket提供了一个中止功能,它会通知服务器别等了,我没有数据过来了。
 22  */
 23 
 24 public class ClientDemo {
 25     public static void main(String[] args) throws IOException {
 26         // 客户端socket对象
 27         Socket s = new Socket("lpp-PC", 12345);
 28 
 29         // 封装数据源
 30         BufferedReader br = new BufferedReader(new FileReader("a.txt"));
 31 
 32         // 封装通道内流
 33         BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
 34                 s.getOutputStream()));
 35 
 36         // 写入数据
 37         String line = null;
 38         while ((line = br.readLine()) != null) {
 39             bw.write(line);
 40             bw.newLine();
 41             bw.flush();
 42         }
 43 
 44         // // 为了告诉服务器写到这里就可以停止了,额外增加一个标记,自定义一个结束标记
 45         // bw.write("over");
 46         // bw.newLine();
 47         // bw.flush();
 48         
 49         //socket提供了一个中止功能,它会通知服务器别等了,我没有数据过来了。
 50         s.shutdownOutput();
 51         
 52         // 接受服务器的反馈
 53         BufferedReader brClient = new BufferedReader(new InputStreamReader(
 54                 s.getInputStream()));
 55         String str = brClient.readLine();
 56         System.out.println(str);
 57 
 58         // 释放资源
 59         br.close();
 60         s.close();
 61     }
 62 }
 63 
 64 
 65 //------------------------------------------
 66 //下面是服务器端的代码
 67 
 68 
 69 import java.io.BufferedReader;
 70 import java.io.BufferedWriter;
 71 import java.io.FileReader;
 72 import java.io.FileWriter;
 73 import java.io.IOException;
 74 import java.io.InputStreamReader;
 75 import java.io.OutputStreamWriter;
 76 import java.net.ServerSocket;
 77 import java.net.Socket;
 78 
 79 public class ServerDemo {
 80     public static void main(String[] args) throws IOException {
 81         // 服务端socke对象
 82         ServerSocket ss = new ServerSocket(12345);
 83 
 84         // 监听客户端,获取socke对象
 85         Socket s = ss.accept();
 86 
 87         // 封装目标文件
 88         BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
 89 
 90         // 封装通道中的输入流
 91         BufferedReader br = new BufferedReader(new InputStreamReader(
 92                 s.getInputStream()));
 93 
 94         // 读取数据,并将数据写入文件
 95         String line = null;
 96         while ((line = br.readLine()) != null) {
 97             // if ("over".equals(line)) {
 98             // break;
 99             // }
100             bw.write(line);
101             bw.newLine();
102             bw.flush();
103         }
104 
105         // 在文件写出完毕后,给客户端一个反馈,
106         BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(
107                 s.getOutputStream()));
108         bwServer.write("数据写入完毕");
109         bwServer.newLine();
110         bwServer.flush();
111 
112         // 释放资源
113         bw.close();
114         s.close();
115 
116     }
117 }

 //======================================

//下面的这个例子是客户端读取的是图片文件/视频文件。而服务器会对象通过TCP协议读取到的数据写到对应格式的文中去。

 1 //先是服务器端的class文件
 2 
 3 import java.io.BufferedInputStream;
 4 import java.io.BufferedOutputStream;
 5 import java.io.FileOutputStream;
 6 import java.io.IOException;
 7 import java.io.OutputStream;
 8 import java.net.ServerSocket;
 9 import java.net.Socket;
10 
11 public class ServerDemo {
12     public static void main(String[] args) throws IOException {
13         // 服务端socke对象
14         ServerSocket ss = new ServerSocket(23456);
15 
16         // 监听客户端,获取socket
17         Socket s = ss.accept();
18 
19         // 封装通道内流数据
20         BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
21 
22         // 封装图标目的地
23         BufferedOutputStream bos = new BufferedOutputStream(
24                 new FileOutputStream("lpp.jpg"));
25 
26         byte[] bys = new byte[1024];
27         int len = 0;
28         while ((len = bis.read(bys)) != -1) {
29             bos.write(bys, 0, len);    
30             bos.flush(); // 尤其是在通道内部使用时,必须使用flush否则丢包
31         }
32 
33         // 给一个反馈
34         OutputStream os = s.getOutputStream();
35         os.write("图片上传成功".getBytes());
36 
37         // 释放资源
38         bos.close();
39         s.close();
40 
41     }
42 }
43 
44 
45 //------------------------------------------------
46 //下面的是客户端的class文件
47 
48 import java.io.BufferedInputStream;
49 import java.io.BufferedOutputStream;
50 import java.io.File;
51 import java.io.FileInputStream;
52 import java.io.IOException;
53 import java.io.InputStream;
54 import java.io.OutputStream;
55 import java.net.Socket;
56 
57 /*
58  * 客户端读取一个数据,通过TCP协议发送到服务器
59  */
60 public class ClientDemo {
61     public static void main(String[] args) throws IOException {
62         // 客户端socke对象
63         Socket s = new Socket("lll-PC", 23456);
64 
65         // 封装数据源
66         BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
67                 "a.jpg"));
68 
69         // 封装通道数据流
70         BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
71 
72         byte[] bys = new byte[1024];
73         int len = 0;
74         while ((len = bis.read(bys)) != -1) {
75             bos.write(bys, 0, len);
76             bos.flush();  //尤其是在通道内部使用时,必须使用flush否则丢包
77         }
78 
79         // 读取反馈,关闭写入流,并告知服务器端,服务器端的阻塞不再等待向下执行
80         s.shutdownOutput();
81 
82         InputStream is = s.getInputStream();
83         byte[] buf = new byte[1024];
84         int len2 = is.read(buf);
85         String clientStr = new String(buf, 0, len2);
86         System.out.println(clientStr);
87 
88         // 释放资源
89         bis.close();
90         s.close();
91 
92     }
93 }

 

推荐阅读