1. TCP发送数据
- Java中的TCP通信
- Java对基于TCP协议的的网络提供了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生IO流来进行网络通信。
- Java为客户端提供了Socket类,为服务器端提供了ServerSocket类
构造方法
相关方法
- 示例代码
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",10000); //获取输出流,写数据 //OutputStream getOutputStream() 返回此套接字的输出流 OutputStream os = s.getOutputStream(); os.write("hello,tcp,我来了".getBytes()); //释放资源 s.close(); } }
2. TCP接收数据【应用】
- 构造方法: 创建绑定到指定端口的服务器套接字
ServletSocket(int port)
- 相关方法:监听要连接到此的套接字并接受它
Socket accept()
注意事项
- accept方法是阻塞的,作用就是等待客户端连接
- 客户端创建对象并连接服务器,此时是通过三次握手协议,保证跟服务器之间的连接
- 针对客户端来讲,是往外写的,所以是输出流
针对服务器来讲,是往里读的,所以是输入流
- read方法也是阻塞的
- 客户端在关流的时候,还多了一个往服务器写结束标记的动作
- 最后一步断开连接,通过四次挥手协议保证连接终止
- 三次握手和四次挥手
- 三次握手
- 四次挥手
3. TCP程序练习
案例需求
客户端:发送数据,接受服务器反馈
服务器:收到消息后给出反馈
案例分析
客户端创建对象,使用输出流输出数据
服务端创建对象,使用输入流接受数据
服务端使用输出流给出反馈数据
客户端使用输入流接受反馈数据代码实现
// 客户端 public class ClientDemo { public static void main(String[] args) throws IOException { Socket socket = new Socket("127.0.0.1",10000); OutputStream os = socket.getOutputStream(); os.write("hello".getBytes()); // os.close();如果在这里关流,会导致整个socket都无法使用 socket.shutdownOutput();//仅仅关闭输出流.并写一个结束标记,对socket没有任何 影响 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String line; while((line = br.readLine())!=null){ System.out.println(line); } br.close(); os.close(); socket.close(); } } // 服务器 public class ServerDemo { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(10000); Socket accept = ss.accept(); InputStream is = accept.getInputStream(); int b; while((b = is.read())!=-1){ System.out.println((char) b); } System.out.println("看看我执行了吗?"); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream())); bw.write("你谁啊?"); bw.newLine(); bw.flush(); bw.close(); is.close(); accept.close(); ss.close(); } }
4. TCP程序文件上传练习【应用】
案例需求
客户端:数据来自于本地文件,接收服务器反馈
服务器:接收到的数据写入本地文件,给出反馈
案例分析
- 创建客户端对象,创建输入流对象指向文件,每读一次数据就给服务器输出一次数据,输出
结束后使用shutdownOutput()方法告知服务端传输结束
创建服务器对象,创建输出流对象指向文件,每接受一次数据就使用输出流输出到文件中,
传输结束后。使用输出流给客户端反馈信息
- 客户端接受服务端的回馈信息
相关方法
代码实现
// 客户端 public class ClientDemo { public static void main(String[] args) throws IOException { Socket socket = new Socket("127.0.0.1",10000); //是本地的流,用来读取本地文件的. BufferedInputStream bis = new BufferedInputStream(new FileInputStream("socketmodule\\ClientDir\\1.jpg")); //写到服务器 --- 网络中的流 OutputStream os = socket.getOutputStream(); BufferedOutputStream bos = new BufferedOutputStream(os); int b; while((b = bis.read())!=-1){ bos.write(b);//通过网络写到服务器中 } bos.flush(); //给服务器一个结束标记,告诉服务器文件已经传输完毕 socket.shutdownOutput(); BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String line; while((line = br.readLine()) !=null){ System.out.println(line); } bis.close(); socket.close(); } }
// 服务器 public class ServerDemo { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(10000); Socket accept = ss.accept(); //网络中的流,从客户端读取数据的 BufferedInputStream bis = new BufferedInputStream(accept.getInputStream()); //本地的IO流,把数据写到本地中,实现永久化存储 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("socketmodule\\ServerDir\\copy.jpg")); int b; while((b = bis.read()) !=-1){ bos.write(b); } BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(accept.getOutputStream())); bw.write("上传成功"); bw.newLine(); bw.flush(); bos.close(); accept.close(); ss.close(); } }