Java网络编程7.TCP网络编程之练习

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cmm0401/article/details/82824312

一、TCP网络编程之客户端键盘录入-服务器控制台输出

1、键盘录入数据

  • BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  • BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));

2、TCP网络编程之客户端键盘录入服务器控制台输出

  • 数据流向:客户端键盘录入到通道内的输出流。服务器端从通道内的输入流到控制台。

(1)服务器端

package cn.itcast_08;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
	public static void main(String[] args) throws IOException {
		// 创建服务器Socket对象
		ServerSocket ss = new ServerSocket(22222);
		// 监听客户端连接
		Socket s = ss.accept();
		// 包装通道内容的流
		BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
		String line = null;
		while ((line = br.readLine()) != null) {
			System.out.println(line);
		}
		// br.close();
		s.close();
		// ss.close();
	}
}

(2)客户端

package cn.itcast_08;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
/*
 * 客户端键盘录入,服务器输出到控制台
 */
public class ClientDemo {
	public static void main(String[] args) throws IOException {
		// 创建客户端Socket对象
		Socket s = new Socket("192.168.12.92", 22222);
		// 键盘录入数据
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		// 把通道内的流给包装一下
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		String line = null;
		while ((line = br.readLine()) != null) {
			// 键盘录入数据要自定义结束标记
			if ("886".equals(line)) {
				break;
			}
			bw.write(line);
			bw.newLine();
			bw.flush();
		}
		// 释放资源
		// bw.close();
		// br.close();
		s.close();
	}
}

二、TCP网络编程之客户端键盘录入-服务器输出到文件

  • 数据流向:客户端键盘录入到通道内的输出流。服务器端从通道内的输入流到文本文件。

(1)服务器端

package cn.itcast_09;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
	public static void main(String[] args) throws IOException {
		// 创建服务器Socket对象
		ServerSocket ss = new ServerSocket(23456);
		// 监听客户端连接
		Socket s = ss.accept();
		// 封装通道内的数据
		BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
		// 封装文本文件
		BufferedWriter bw = new BufferedWriter(new FileWriter("a.txt"));
		String line = null;
		while ((line = br.readLine()) != null) {
			bw.write(line);
			bw.newLine();
			bw.flush();
		}
		bw.close();
		// br.close();
		s.close();
		// ss.close();
	}
}

(2)客户端

package cn.itcast_09;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

/*
 * 客户端键盘录入,服务器输出文本文件
 */
public class ClientDemo {
	public static void main(String[] args) throws IOException {
		// 创建客户端Socket对象
		Socket s = new Socket("192.168.12.92", 23456);
		// 封装键盘录入
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		// 封装通道内的数据
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		String line = null;
		while ((line = br.readLine()) != null) {
			if ("over".equals(line)) {
				break;
			}
			bw.write(line);
			bw.newLine();
			bw.flush();
		}
		// bw.close();
		// br.close();
		s.close();
	}
}

三、TCP网络编程之客户端文本文件-服务器控制台输出

  • 数据流向:客户端文本文件到通道内的输出流。服务器端从通道内的输入流到控制台。

(1)服务器端

package cn.itcast_10;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
	public static void main(String[] args) throws IOException {
		// 创建服务器Socket对象
		ServerSocket ss = new ServerSocket(34567);
		// 监听客户端连接
		Socket s = ss.accept();
		// 封装通道内的流
		BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
		String line = null;
		while ((line = br.readLine()) != null) {
			System.out.println(line);
		}
		s.close();
	}
}

(2)客户端

package cn.itcast_10;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
/*
 * 客户端文本文件,服务器输出到控制台
 */
public class ClientDemo {
	public static void main(String[] args) throws IOException {
		// 创建Socket对象
		Socket s = new Socket("192.168.12.92", 34567);
		// 封装文本文件
		BufferedReader br = new BufferedReader(new FileReader("InetAddressDemo.java"));
		// 封装通道内的流
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
		String line = null;
		while ((line = br.readLine()) != null) {
			bw.write(line);
			bw.newLine();
			bw.flush();
		}
		br.close();
		s.close();
	}
}

四、TCP网络编程之客户端文本文件-服务器文本文件:文件上传功能

  • 数据流向:客户端文本文件到通道内的输出流。服务器端从通道内的输入流到文本文件。

(1)服务器端

package cn.itcast_12;
import java.io.BufferedReader;
import java.io.BufferedWriter;
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 UploadServer {
	public static void main(String[] args) throws IOException {
		// 创建服务器端的Socket对象
		ServerSocket ss = new ServerSocket(11111);
		// 监听客户端连接
		Socket s = ss.accept();// 阻塞式方法
		// 封装通道内的流
		BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
		// 封装文本文件
		BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));
		String line = null;
		while ((line = br.readLine()) != null) { // 阻塞式方法
			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();
	}
}

(2)客户端

package cn.itcast_12;
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;
public class UploadClient {
	public static void main(String[] args) throws IOException {
		// 创建客户端Socket对象
		Socket s = new Socket("192.168.12.92", 11111);
		// 封装文本文件
		BufferedReader br = new BufferedReader(new FileReader("InetAddressDemo.java"));
		// 封装通道内流
		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 client = brClient.readLine(); // 阻塞式方法
		System.out.println(client);
		// 释放资源
		br.close();
		s.close();
	}
}

PS:/*
 * 按照我们正常的思路加入反馈信息,结果却没反应。为什么呢?
 * 读取文本文件是可以以null作为结束信息的,但是呢,通道内是不能这样结束信息的。
 * 所以,服务器根本就不知道你结束了。而你还想服务器给你反馈。所以,就相互等待了。
 * 如何解决呢?
 * A: 再多写一条数据,告诉服务器,读取到这条数据说明我就结束,你也结束吧。
 *         这样做可以解决问题,但是不好,不推荐!
 * B: Socket对象提供了一种解决方案:Socket提供了一个终止,它会通知服务器你别等了,我没有数据过来了:
 *         public void shutdownOutput()
 */

五、TCP网络编程之客户端图片-服务器图片:图片上传功能

  • 数据流向:客户端图片到通道内的输出流。服务器端从通道内的输入流到图片。

(1)服务器端      bos.flush()防止数据丢失

package cn.itcast_13;
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 UploadServer {
	public static void main(String[] args) throws IOException {
		// 创建服务器Socket对象
		ServerSocket ss = new ServerSocket(19191);
		// 监听客户端连接
		Socket s = ss.accept();
		// 封装通道内流
		BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
		// 封装图片文件
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("mn.jpg"));
		byte[] bys = new byte[1024];
		int len = 0;
		while ((len = bis.read(bys)) != -1) {
			bos.write(bys, 0, len);
			bos.flush();
		}
		// 给客户端一个反馈信息
		OutputStream os = s.getOutputStream();
		os.write("图片上传成功".getBytes());
		bos.close();
		s.close();
	}
}

(2)客户端      bos.flush():防止数据丢失

package cn.itcast_13;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
public class UploadClient {
	public static void main(String[] args) throws IOException {
		// 创建客户端Socket对象
		Socket s = new Socket("192.168.12.92", 19191);
		// 封装图片文件
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("林青霞.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();
		}
		s.shutdownOutput();
		// 读取服务器端给出的反馈信息
		InputStream is = s.getInputStream();
		byte[] bys2 = new byte[1024];
		int len2 = is.read(bys2);
		String client = new String(bys2, 0, len2);
		System.out.println(client);
		// 释放资源
		bis.close();
		s.close();
	}
}

六、TCP传输容易出现的问题

  • 客户端连接上服务端,两端都在等待,没有任何数据传输。
  • 通过例程分析:因为read方法或者readLine方法是阻塞式方法。
  • 解决办法:
    • 自定义结束标志。
    • 使用shutdownInput,shutdownOutput方法(推荐)。

 

猜你喜欢

转载自blog.csdn.net/cmm0401/article/details/82824312
今日推荐