在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理Java知识点的第三十一篇博客。
本篇博客介绍了Java的利用TCP进行网络编程。
本系列博客所有Java代码都使用IntelliJ IDEA编译运行,版本为2022.1。所用JDK版本为JDK11。
目录
这一部分接上一篇博客介绍网络编程,但是内容全部与TCP有关。
TCP通信协议在通信两端各建立一个Socket对象,形成网络虚拟链路,随后就可以通过虚拟链路进行通信。
Java对基于TCP协议的网络提供了良好的封装,使用Socket对象代表两端的通信端口,通过Socket产生IO流进行网络通信。Java为客户端提供了Socket类,为服务器端提供ServerSocker类。
发送数据需要创建一个客户端的Socket对象(需要导包,import java.net.Socket),然后获取输出流,写数据,最后释放资源(用close)。
创建客户端的Socket对象的方法是:
Socket(String host,int port)
host是主机名或IP地址,port是端口。
写数据的方法是:
OutputStream getOutputStream()
接收数据首先创建服务器端的Socket对象ServerSocket(需要导包,import java.net.ServerSocket),然后获取输入流,读数据,把数据显示在控制台,最后释放资源(用close)
创建服务器端的Socket对象的方法是:
ServerSocket(int port)
port是端口。
然后要监听客户端连接,返回一个Socket对象:
Socket accept()
获取输入流读数据的方法是:
InputStream getInputStream()
- import java.io.IOException;
- import java.net.Socket;
- import java.io.OutputStream;
- public class tcpoutput {
- public static void main(String[] args) throws IOException {
- Socket s = new Socket("LAPTOP",10000);
- OutputStream os = s.getOutputStream();
- os.write("Hello Java".getBytes());
- os.close();
- }
- }
这是发送数据的代码,将Hello Java发送。
- import java.io.IOException;
- import java.net.Socket;
- import java.net.ServerSocket;
- import java.io.InputStream;
- public class tcpinput {
- public static void main(String[] args) throws IOException {
- ServerSocket ss = new ServerSocket(10000);
- Socket s = ss.accept();
- InputStream is = s.getInputStream();
- byte[] data = new byte[1024];
- int len = is.read(data);
- System.out.println(new String(data,0,len));
- is.close();
- }
- }
这是接收数据的代码。
下面是先执行tcpinput类,随后执行tcpoutput类后的结果:
tcpinput类的输出:
Hello Java
tcpoutput类无输出。
要求服务器获取数据后给出反馈。
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.Socket;
- public class tcptest1A {
- public static void main(String[] args) throws IOException {
- Socket s = new Socket("LAPTOP",10000);
- OutputStream os = s.getOutputStream();
- os.write("TCP test 1 2022/07/23".getBytes());
-
- InputStream is = s.getInputStream();
- byte[] data = new byte[1024];
- int len = is.read(data);
- System.out.println(new String(data,0,len));
- is.close();
- os.close();
- }
- }
这是对应客户端,先发送数据,然后接收反馈并进行输出。
- import java.io.IOException;
- import java.net.Socket;
- import java.net.ServerSocket;
- import java.io.InputStream;
- import java.io.OutputStream;
- public class tcptest1B {
- public static void main(String[] args) throws IOException {
- ServerSocket ss = new ServerSocket(10000);
- Socket s = ss.accept();
- InputStream is = s.getInputStream();
- byte[] data = new byte[1024];
- int len = is.read(data);
- System.out.println(new String(data, 0, len));
-
- OutputStream os = s.getOutputStream();
- os.write("Done".getBytes());
- os.close();
- is.close();
- }
- }
这是对应服务器端,先接收数据并输出,然后给出反馈。
下面是先执行tcptest1B类,随后执行tcptest1A类的结果:
tcptest1A类的结果是:
Done
tcptest1B类的结果是:
TCP test 1 2022/07/23
要求客户端的数据是从键盘录入的。
- import java.io.*;
- import java.net.Socket;
- public class tcptest2A {
- public static void main(String[] args) throws IOException {
- Socket s = new Socket("LAPTOP",10000);
- InputStream is = System.in;
- InputStreamReader isr = new InputStreamReader(is);
- BufferedReader br = new BufferedReader(isr);
-
- String str;
- while((str = br.readLine()) != null){
- if(str.equals("886")){
- break;
- }
- OutputStream os = s.getOutputStream();
- OutputStreamWriter osw = new OutputStreamWriter(os);
- BufferedWriter bw = new BufferedWriter(osw);
- bw.write(str);
- bw.newLine();
- bw.flush();
- }
- br.close();
- s.close();
- }
- }
这是客户端内容,要求只要输入的不是886,就一直发送输入的内容。
- import java.io.*;
- import java.net.Socket;
- import java.net.ServerSocket;
-
- public class tcptest2B {
- public static void main(String[] args) throws IOException {
- ServerSocket ss = new ServerSocket(10000);
- Socket s = ss.accept();
-
- InputStream is = s.getInputStream();
- InputStreamReader isr = new InputStreamReader(is);
- BufferedReader br = new BufferedReader(isr);
- String str;
- while((str = br.readLine())!=null) {
- System.out.println(str);
- }
- ss.close();
- }
- }
这是服务器端内容,只要有输入就一直显示在屏幕上。
下面是先执行tcptest2B类,随后执行tcptest2A类的结果:
这是tcptest2A类的输入:
Hello world
Hello Java
TCP test
886
这是tcptest2B类的输出:
Hello world
Hello Java
TCP test
要求服务器将数据写入文本文件。
- import java.io.*;
- import java.net.Socket;
- public class tcptest3A {
- public static void main(String[] args) throws IOException {
- Socket s = new Socket("LAPTOP",10000);
- InputStream is = System.in;
- InputStreamReader isr = new InputStreamReader(is);
- BufferedReader br = new BufferedReader(isr);
-
- String str;
- while((str = br.readLine()) != null){
- if(str.equals("886")){
- break;
- }
- OutputStream os = s.getOutputStream();
- OutputStreamWriter osw = new OutputStreamWriter(os);
- BufferedWriter bw = new BufferedWriter(osw);
- bw.write(str);
- bw.newLine();
- bw.flush();
- }
- br.close();
- s.close();
- }
- }
这是客户端内容,要求只要输入的不是886,就一直发送输入的内容。
- import java.io.*;
- import java.net.Socket;
- import java.net.ServerSocket;
-
- public class tcptest3B {
- public static void main(String[] args) throws IOException {
- ServerSocket ss = new ServerSocket(10000);
- Socket s = ss.accept();
-
- InputStream is = s.getInputStream();
- InputStreamReader isr = new InputStreamReader(is);
- BufferedReader br = new BufferedReader(isr);
- BufferedWriter bw = new BufferedWriter(new FileWriter("test1.txt"));
- String str;
- while((str = br.readLine())!=null) {
- bw.write(str);
- bw.newLine();
- bw.flush();
- }
- br.close();
- bw.close();
- ss.close();
- }
- }
这是服务器端,只要读取有数据就写入文件。
下面是先执行tcptest3B类,随后执行tcptest3A类的结果:
这是tcptest3A类的输入:
Hello Java
TCP test
Today is August 20th in 2022
It is about 21 o'clock
886
tcptest3B类无输出,文件test1.txt的内容是:
Hello Java
TCP test
Today is August 20th in 2022
It is about 21 o'clock
要求客户端从文本文件中获取要发送的信息。
- import java.io.*;
- import java.net.Socket;
- public class tcptest4A {
- public static void main(String[] args) throws IOException {
- Socket s = new Socket("LAPTOP",10000);
- BufferedReader br = new BufferedReader(new FileReader("test1.txt"));
-
- String str;
- while((str = br.readLine()) != null){
- if(str.equals("886")){
- break;
- }
- OutputStream os = s.getOutputStream();
- OutputStreamWriter osw = new OutputStreamWriter(os);
- BufferedWriter bw = new BufferedWriter(osw);
- bw.write(str);
- bw.newLine();
- bw.flush();
- }
- br.close();
- s.close();
- }
- }
这是客户端内容,只要文件中没有读到886就一直发送读到的数据。
- import java.io.*;
- import java.net.Socket;
- import java.net.ServerSocket;
-
- public class tcptest4B {
- public static void main(String[] args) throws IOException {
- ServerSocket ss = new ServerSocket(10000);
- Socket s = ss.accept();
-
- InputStream is = s.getInputStream();
- InputStreamReader isr = new InputStreamReader(is);
- BufferedReader br = new BufferedReader(isr);
- BufferedWriter bw = new BufferedWriter(new FileWriter("test2.txt"));
- String str;
- while((str = br.readLine())!=null) {
- bw.write(str);
- bw.newLine();
- bw.flush();
- }
- bw.close();
- ss.close();
- }
- }
这是服务器端内容,只要有数据传入,就输出到另一个文件。
test1.txt准备的内容是:
Hello Java
TCP test
Today is August 20th in 2022
It is about 21 o'clock
886
下面是先执行tcptest4B类,随后执行tcptest4A类的结果:
tcptest4A类和tcptest4B类均无输出。
下面是test2.txt的内容:
Hello Java
TCP test
Today is August 20th in 2022
It is about 21 o'clock
要求服务器接收完毕后给出反馈。
- import java.io.*;
- import java.net.Socket;
- public class tcptest5A {
- public static void main(String[] args) throws IOException {
- Socket s = new Socket("LAPTOP",10000);
- BufferedReader br = new BufferedReader(new FileReader("test1.txt"));
-
- String str;
- while((str = br.readLine()) != null){
- if(str.equals("886")){
- break;
- }
- OutputStream os = s.getOutputStream();
- OutputStreamWriter osw = new OutputStreamWriter(os);
- BufferedWriter bw = new BufferedWriter(osw);
- bw.write(str);
- bw.newLine();
- bw.flush();
- }
-
- s.shutdownOutput();
- InputStream is = s.getInputStream();
- byte[] data = new byte[1024];
- int len = is.read(data);
- System.out.println(new String(data,0,len));
- br.close();
- s.close();
- is.close();
- }
- }
这是客户端内容,只要文件中没有读到886就一直发送读到的数据,发送完毕后输出得到的反馈。
- import java.io.*;
- import java.net.Socket;
- import java.net.ServerSocket;
-
- public class tcptest5B {
- public static void main(String[] args) throws IOException {
- ServerSocket ss = new ServerSocket(10000);
- Socket s = ss.accept();
-
- InputStream is = s.getInputStream();
- InputStreamReader isr = new InputStreamReader(is);
- BufferedReader br = new BufferedReader(isr);
- BufferedWriter bw = new BufferedWriter(new FileWriter("test2.txt"));
- String str;
- while((str = br.readLine())!=null) {
- bw.write(str);
- bw.newLine();
- bw.flush();
- }
-
- OutputStream os = s.getOutputStream();
- os.write("Done".getBytes());
- os.close();
- bw.close();
- ss.close();
- }
- }
这是服务器端内容,只要有数据传入,就输出到另一个文件,接收完毕后给出反馈。
这是test1.txt准备的内容:
Hello Java
TCP test
Today is August 20th in 2022
It is about 21 o'clock
886
下面是先执行tcptest5B类,随后执行tcptest5A类的结果:
tcptest5B类无输出。tcptest5A类的输出是:
Done
下面是test2.txt的内容:
Hello Java
TCP test
Today is August 20th in 2022
It is about 21 o'clock
要求用多线程实现文件上传。
- import java.io.*;
- import java.net.Socket;
- public class tcptest6A {
- public static void main(String[] args) throws IOException {
- Socket s = new Socket("LAPTOP",10000);
- BufferedReader br = new BufferedReader(new FileReader("test1.txt"));
-
- String str;
- while((str = br.readLine()) != null){
- if(str.equals("886")){
- break;
- }
- OutputStream os = s.getOutputStream();
- OutputStreamWriter osw = new OutputStreamWriter(os);
- BufferedWriter bw = new BufferedWriter(osw);
- bw.write(str);
- bw.newLine();
- bw.flush();
- }
-
- s.shutdownOutput();
- br.close();
- InputStream is = s.getInputStream();
- byte[] data = new byte[1024];
- int len = is.read(data);
- System.out.println(new String(data,0,len));
- s.close();
- is.close();
- }
- }
这是客户端内容,只要文件中没有读到886就一直发送读到的数据,发送完毕后输出得到的反馈。
- import java.io.*;
- import java.net.ServerSocket;
- import java.net.Socket;
-
- public class tcptestthread implements Runnable{
- private Socket s;
- public tcptestthread(){}
- public tcptestthread(Socket s){
- this.s = s;
- }
-
- public void run(){
- try {
- InputStream is = s.getInputStream();
- InputStreamReader isr = new InputStreamReader(is);
- BufferedReader br = new BufferedReader(isr);
- BufferedWriter bw = new BufferedWriter(new FileWriter("test2.txt"));
- String str;
- while ((str = br.readLine()) != null) {
- bw.write(str);
- bw.newLine();
- bw.flush();
- }
-
- OutputStream os = s.getOutputStream();
- os.write("Done".getBytes());
- s.close();
- }catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
这是实现多线程的类,将数据写入文件,并给出反馈。
- import java.io.*;
- import java.net.Socket;
- import java.net.ServerSocket;
-
- public class tcptest6B {
- public static void main(String[] args) throws IOException {
- ServerSocket ss = new ServerSocket(10000);
- while(true){
- Socket s = ss.accept();
- tcptestthread ttt = new tcptestthread(s);
- Thread t = new Thread(ttt);
- t.start();
- }
- }
- }
这是服务器端,接收数据并启动tcptestthread的多线程。
这是test1.txt准备的内容:
Hello Java
TCP test
Today is August 20th in 2022
It is about 21 o'clock
886
下面是先执行tcptest6B类,随后执行tcptest6A类的结果(在文件传输完毕后结束了tcptest6B类):
tcptest6B类无输出。tcptest6A类的输出是:
Done
下面是test2.txt的内容:
Hello Java
TCP test
Today is August 20th in 2022
It is about 21 o'clock