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 }