java中的网络编程之TCP协议的详细介绍,以及如何使用,同时我在下面举2例说明如何搭配IO流进行操作,
/*
*TCP
*建立连接,形成传输数据的通道;
*在连接中进行大数据量传输;
*通过三次握手完成连接,是可靠协议;
*必须建立连接,效率会稍低
*/ /*
* TCP传输
* Socket和ServerSocket建立客户端和服务器端建立连接后,
* 通过Socket中的IO流进行数据的传输关闭socket同样,
* 客户端与服务器端是两个独立的应用程序。
*/ //-------------------------------
//下面的是TCP协议的服务器端代码 import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket; /*
* TCP协议接收数据
* 1.创建接收端的socket对象
* 2.监听客户端,返回一个对应的socket对象
* 3.获取输入流,读取数据,显示在控制台
* 4.释放资源
*/
public class ServerDemo {
public static void main(String[] args) throws IOException {
// 创建接收端socket对象
ServerSocket ss = new ServerSocket(10086); // 监听客户端,返回一个对应的socket对象
// public Socket accept() 侦听并接受到此套接字的连接。
Socket s = ss.accept(); // 阻塞式方法,直到通道建立 // 获取输入流,读取数据
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len = is.read(bys); // 阻塞式方法,直到数据发过来。
String ip = s.getInetAddress().getHostAddress(); String str = new String(bys, 0, len);
System.out.println(str); // 释放资源
s.close();
ss.close(); // 这个不应该关闭
}
} //-------------------------------
//下面是客户端TCP协议的代码
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket; /*
*TCP协议发送数据:
* 1.创建发送端socket对象
* 这一步如果成功,就说明链接已经成功了。
* 2.获取输出流,写数据
* 3.释放资源
*
*TCP一些服务器必须先开启,保证通道简历,否则直接报错。
*java.net.ConnectException: Connection refused: connect
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 创建发送端socket对象
// Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号。
Socket socket = new Socket("lpp-PC", 10086);
//“lpp-PC”里面的字符串一般使用服务器端的IP地址代替。 // 获取输出流,写数据
OutputStream os = socket.getOutputStream();
os.write("TCP coming~~~".getBytes()); // 关闭资源
os.close();
}
}
//==================================
//---------------------------------------------------------------
//下面给出一个案例:客户端从指定文本文件读取数据,发送到服务器端,
//服务器将接收到的数据,再次写入到一个新的文本文件。数据的写/出是字节
//流 //首先给出的是客户端的代码:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket; /*
* 客户端从文本文件中读取数据,服务器得到数据写入到文本文件,
* 为了在服务器写完数据后,给客户端一个反馈,但是直接在通道内额外的添加数据是不行,会导致双方一直保持等待状态
* 方案
* 1: 在客户端里面额外增加一条语句告诉服务器结束的标志。
* 2: 直接使用JDK给出的方法:shutdownOutput();socket提供了一个中止功能,它会通知服务器别等了,我没有数据过来了。
*/ public class ClientDemo {
public static void main(String[] args) throws IOException {
// 客户端socket对象
Socket s = new Socket("lpp-PC", 12345); // 封装数据源
BufferedReader br = new BufferedReader(new FileReader("a.txt")); // 封装通道内流
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream())); // 写入数据
String line = null;
while ((line = br.readLine()) != null) {
bw.write(line);
bw.newLine();
bw.flush();
} // // 为了告诉服务器写到这里就可以停止了,额外增加一个标记,自定义一个结束标记
// bw.write("over");
// bw.newLine();
// bw.flush(); //socket提供了一个中止功能,它会通知服务器别等了,我没有数据过来了。
s.shutdownOutput(); // 接受服务器的反馈
BufferedReader brClient = new BufferedReader(new InputStreamReader(
s.getInputStream()));
String str = brClient.readLine();
System.out.println(str); // 释放资源
br.close();
s.close();
}
} //------------------------------------------
//下面是服务器端的代码 import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket; public class ServerDemo {
public static void main(String[] args) throws IOException {
// 服务端socke对象
ServerSocket ss = new ServerSocket(12345); // 监听客户端,获取socke对象
Socket s = ss.accept(); // 封装目标文件
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt")); // 封装通道中的输入流
BufferedReader br = new BufferedReader(new InputStreamReader(
s.getInputStream())); // 读取数据,并将数据写入文件
String line = null;
while ((line = br.readLine()) != null) {
// if ("over".equals(line)) {
// break;
// }
bw.write(line);
bw.newLine();
bw.flush();
} // 在文件写出完毕后,给客户端一个反馈,
BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(
s.getOutputStream()));
bwServer.write("数据写入完毕");
bwServer.newLine();
bwServer.flush(); // 释放资源
bw.close();
s.close(); }
}
//======================================
//下面的这个例子是客户端读取的是图片文件/视频文件。而服务器会对象通过TCP协议读取到的数据写到对应格式的文中去。
//先是服务器端的class文件 import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket; public class ServerDemo {
public static void main(String[] args) throws IOException {
// 服务端socke对象
ServerSocket ss = new ServerSocket(23456); // 监听客户端,获取socket
Socket s = ss.accept(); // 封装通道内流数据
BufferedInputStream bis = new BufferedInputStream(s.getInputStream()); // 封装图标目的地
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream("lpp.jpg")); byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
bos.flush(); // 尤其是在通道内部使用时,必须使用flush否则丢包
} // 给一个反馈
OutputStream os = s.getOutputStream();
os.write("图片上传成功".getBytes()); // 释放资源
bos.close();
s.close(); }
} //------------------------------------------------
//下面的是客户端的class文件 import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket; /*
* 客户端读取一个数据,通过TCP协议发送到服务器
*/
public class ClientDemo {
public static void main(String[] args) throws IOException {
// 客户端socke对象
Socket s = new Socket("lll-PC", 23456); // 封装数据源
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(
"a.jpg")); // 封装通道数据流
BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream()); byte[] bys = new byte[1024];
int len = 0;
while ((len = bis.read(bys)) != -1) {
bos.write(bys, 0, len);
bos.flush(); //尤其是在通道内部使用时,必须使用flush否则丢包
} // 读取反馈,关闭写入流,并告知服务器端,服务器端的阻塞不再等待向下执行
s.shutdownOutput(); InputStream is = s.getInputStream();
byte[] buf = new byte[1024];
int len2 = is.read(buf);
String clientStr = new String(buf, 0, len2);
System.out.println(clientStr); // 释放资源
bis.close();
s.close(); }
}