3 TCP通信程序
3.1 TCP通信原理
- TCP通信协议是一种可靠的网络协议, 它在通信的两端名建立一个Socke对象, 从而在通信的两端形成网络虚拟链路
- 一旦建立了 虚拟的网络链路,两端的程序就可以通过虚拟链路进行通信
- Java对基于TCP协议的的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生l0流来进行网络通信
- Java为客户端提供了Socket类,为服务器端提供了ServerSocket类
3.2 TCP发送数据
- 发送数据的步骤
- 1、创建客户端的Socket对象(Socket):
Socket(String host, int port)
- 2、获取输出流,写数据:
OutputStream对象的getOutputStream()方法
- 3、释放资源:
void close()
- 1、创建客户端的Socket对象(Socket):
- 范例:
package test;import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;public class ClientDemo {public static void main(String[] args) throws IOException {//1、创建客户端的Socket对象(Socket):Socket(String host, int port)Socket s = new Socket("127.0.0.1",1000);//2、获取输出流,写数据:OutputStream对象的getOutputStream()方法OutputStream os = s.getOutputStream();os.write("hello,java".getBytes());//3、释放资源:void close()s.close();}
}
3.3 TCP接收数据
-
接收数据的步骤
- 1、创建服务 器端的Socket对象(ServerSocket):
ServerSocket(int port)
- 2、监听客户端连接, 返回个Socket对象:
Socket accept()
- 3、获取输入流, 读数据,并把数据显示在控制台:
InputStream对象的getInputStream()方法
- 4、释放资源:
void close()
- 1、创建服务 器端的Socket对象(ServerSocket):
-
范例
package test;import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;public class SeverDemo {public static void main(String[] args) throws IOException {//1、创建服务 器端的Socket对象(ServerSocket):ServerSocket(int port)ServerSocket ss = new ServerSocket(1000);//2、监听客户端连接, 返回个Socket对象:Socket accept()Socket s = ss.accept();//3、获取输入流, 读数据,并把数据显示在控制台:InputStream对象的getInputStream()方法InputStream is = s.getInputStream();byte[] bys = new byte[1014];int len = is.read(bys);String data = new String(bys,0,len);System.out.println(data);//4、释放资源:void close()s.close();ss.close();}
}
3.4 案例
3.4.1 练习一:服务器给出反馈
- 客户端
package test;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;public class ClientDemo {public static void main(String[] args) throws IOException {//1、创建客户端的Socket对象(Socket):Socket(String host, int port)Socket s = new Socket("127.0.0.1",1000);//2、获取输出流,写数据:OutputStream对象的getOutputStream()方法OutputStream os = s.getOutputStream();os.write("hello,java".getBytes());//接收服务器反馈InputStream is = s.getInputStream();byte[] bys = new byte[1024];int len = is.read(bys);String data = new String(bys,0,len);System.out.println("客户端:"+data);//3、释放资源:void close()s.close();//客户端:数据已经收到}
}
- 服务器
package test;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class SeverDemo {public static void main(String[] args) throws IOException {//1、创建服务 器端的Socket对象(ServerSocket):ServerSocket(int port)ServerSocket ss = new ServerSocket(1000);//2、监听客户端连接, 返回个Socket对象:Socket accept()Socket s = ss.accept();//3、获取输入流, 读数据,并把数据显示在控制台:InputStream对象的getInputStream()方法InputStream is = s.getInputStream();byte[] bys = new byte[1014];int len = is.read(bys);String data = new String(bys,0,len);System.out.println("服务器:"+data);//给出反馈OutputStream os = s.getOutputStream();os.write("数据已经收到".getBytes());//4、释放资源:void close()s.close();ss.close();//服务器:hello,java}
}
3.4.2 练习二:客户端数据来源于键盘录入
- 客户端
package test;import java.io.*;
import java.net.Socket;public class ClientDemo {public static void main(String[] args) throws IOException {//创建客户端的Socket对象(Socket):Socket(String host, int port)Socket s = new Socket("127.0.0.1",1000);//数据来源于键盘录入,直到886停止System.out.println("请输入数据");BufferedReader br = new BufferedReader(new InputStreamReader(System.in));//封装输出流对象BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));String line;while((line= br.readLine())!=null) {if("886".equals(line)) {break;}//获取输出流对象bw.write(line);bw.newLine();bw.flush();}//释放资源s.close();// hello
// 886}
}
- 服务器
package test;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;public class SeverDemo {public static void main(String[] args) throws IOException {//1、创建服务 器端的Socket对象(ServerSocket):ServerSocket(int port)ServerSocket ss = new ServerSocket(1000);//2、监听客户端连接, 返回个Socket对象:Socket accept()Socket s = ss.accept();//3、获取输入流, 读数据,并把数据显示在控制台:InputStream对象的getInputStream()方法
// InputStream is = s.getInputStream();
// InputStreamReader isr = new InputStreamReader(is);
// BufferedReader br = new BufferedReader(isr);BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));String line;while((line=br.readLine())!=null) {System.out.println(line);}//4、释放资源:void close()s.close();//hello}
}
3.4.3 练习三:服务器数据写入文本文件
- 服务器
package test;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;public class SeverDemo {public static void main(String[] args) throws IOException {//1、创建服务 器端的Socket对象(ServerSocket):ServerSocket(int port)ServerSocket ss = new ServerSocket(1000);//2、监听客户端连接, 返回个Socket对象:Socket accept()Socket s = ss.accept();//3、获取输入流, 读数据,并把数据显示在控制台:InputStream对象的getInputStream()方法BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//把数据写入文本文件BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\test\\java.txt"));String line;while((line=br.readLine())!=null) {bw.write(line);bw.newLine();bw.flush();}//4、释放资源:void close()bw.close();ss.close();//文件中数据:hello}
}
3.4.4 练习四:客户端数据来源于文本文件
- 客户端
package test;import java.io.*;
import java.net.Socket;public class ClientDemo {public static void main(String[] args) throws IOException {//创建客户端的Socket对象(Socket):Socket(String host, int port)Socket s = new Socket("127.0.0.1",1000);//封装文本文件数据BufferedReader br =new BufferedReader(new FileReader("E:\\test\\fos.txt"));//封装输出流对象BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));String line;while((line= br.readLine())!=null) {//获取输出流对象bw.write(line);bw.newLine();bw.flush();}//释放资源br.close();s.close();}
}
3.4.5 练习五:上传文件服务器给出反馈
- 客户端
package test;import java.io.*;
import java.net.Socket;public class ClientDemo {public static void main(String[] args) throws IOException {//创建客户端的Socket对象(Socket):Socket(String host, int port)Socket s = new Socket("127.0.0.1",1000);//封装文本文件数据BufferedReader br =new BufferedReader(new FileReader("E:\\test\\fos.txt"));//封装输出流对象BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));String line;while((line= br.readLine())!=null) {//获取输出流对象bw.write(line);bw.newLine();bw.flush();}// //自定义结束标记
// bw.write("886");
// bw.newLine();
// bw.flush();s.shutdownOutput();//Socket类中方法:表示输出结束//接收反馈BufferedReader brClient = new BufferedReader(new InputStreamReader(s.getInputStream()));String data = brClient.readLine(); //等待读取数据System.out.println("服务器的反馈:"+data); //服务器的反馈:文件上传成功//释放资源br.close();s.close();}
}
- 服务端
package test;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;public class SeverDemo {public static void main(String[] args) throws IOException {//1、创建服务 器端的Socket对象(ServerSocket):ServerSocket(int port)ServerSocket ss = new ServerSocket(1000);//2、监听客户端连接, 返回个Socket对象:Socket accept()Socket s = ss.accept();//3、获取输入流, 读数据,并把数据显示在控制台:InputStream对象的getInputStream()方法BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));//把数据写入文本文件BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\test\\java.txt"));String line;while((line=br.readLine())!=null) { //等待读取数据
// if("886".equals(line)) {
// break;
// }bw.write(line);bw.newLine();bw.flush();}//给出反馈BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));bwServer.write("文件上传成功");bwServer.newLine();bwServer.flush();//4、释放资源:void close()bw.close();ss.close();}
}
3.4.6 练习六:多线程实现文件上传
- 服务端
package test;import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;public class SeverDemo {public static void main(String[] args) throws IOException {//创建服务 器端的Socket对象(ServerSocket):ServerSocket(int port)ServerSocket ss = new ServerSocket(1000);while(true) {//监听客户端连接, 返回个Socket对象:Socket accept()Socket s = ss.accept();//为每一个客户端开启一个线程new Thread(new ServerThread(s)).start();}}
}
- 服务端多线程
package test;import java.io.*;
import java.net.Socket;public class ServerThread implements Runnable {private Socket s;public ServerThread(Socket s) {this.s = s;}@Overridepublic void run() {try {//接收数据写入文本文件BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
// BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\test\\java.txt"));//解决名称冲突问题,上传到不同文件中int count = 0;File file = new File("E:\\test\\["+count+"]java.txt");while(file.exists()) {count++;file = new File("E:\\test\\["+count+"]java.txt");}BufferedWriter bw = new BufferedWriter(new FileWriter(file));String line;while ((line=br.readLine()) != null) {bw.write(line);bw.newLine();bw.flush();}//给出反馈BufferedWriter bwSever =new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));bwSever.write("文件上传成功");bwSever.newLine();bwSever.flush();//释放资源s.close();}catch (IOException e) {e.printStackTrace();}}
}