黑马程序员——网络编程TCP

------- android培训java培训、期待与您交流! ----------

 

TCP特点

1.      面向连接,客户端和服务端必须先建立连接

2.      客户端用Socket来向服务端发出请求,服务端用ServerSocket来获得客户端请求的Socket

3.      通过socket中的getOutputStreamgetInputStream来进行收发数据

4.      需要经过三次握手建立连接,所以数据传输是安全的

 

UDPTCP总结

udp面向无连接,可能会丢失数据, 类似发短信

tcp三次握手建立连接,不会丢失数据, 类似打电话

 

代码示例

客户端

package cn.itcast.tcp;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

public class Client {
	public static void main(String[] args) {
		Socket socket = null;
		try {
			// 创建Socket对象
			socket = new Socket(InetAddress.getLocalHost().getHostName(), 30001);
			// 向服务端写出数据
			OutputStream os = socket.getOutputStream();
			os.write("你好服务端".getBytes());

			// 接收服务端返回的信息
			InputStream is = socket.getInputStream();
			byte[] buffer = new byte[1024];
			int len = is.read(buffer);
			// 将接收的数据转换为字符串
			String data = new String(buffer, 0, len);
			System.out.println(data);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				socket.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}


 

服务端

package cn.itcast.tcp;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
	public static void main(String[] args) {
		ServerSocket ss = null;
		try {
			// 创建ServerSocket对象
			ss = new ServerSocket(30001);
			// 获得客户端请求的Socket
			Socket socket = ss.accept();
			// 获得客户端发送的数据
			InputStream is = socket.getInputStream();
			byte[] buffer = new byte[1024];
			int len = is.read(buffer);
			// 将收到的数据转为字符串
			String data = new String(buffer, 0, len);
			System.out.println(data);
			// 向客户端写出数据
			OutputStream os = socket.getOutputStream();
			os.write("你也好客户端".getBytes());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				ss.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}


 

上传文件, 断点上传应用代码

 

客户端

package cn.itcast.tcp;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;

public class Demo3_uploadClient {

	public static void main(String[] args) throws Exception {

		Socket socket = new Socket(InetAddress.getLocalHost(), 30000); // 建立Socket
		InputStream is = socket.getInputStream(); // 读取服务器信息
		OutputStream os = socket.getOutputStream(); // 写出数据到服务器的对象
		File uploadFile = getFile(); // 得到要上传的文件
		BufferedReader br = new BufferedReader(new InputStreamReader(is)); // 读取服务器的字符信息
		PrintStream ps = new PrintStream(os); // 将信息写出到服务器
		ps.println(uploadFile.getName()); // 将文件名写入到服务器
		ps.println(uploadFile.length()); // 将文件长度写入到服务器

		String result = br.readLine();
		if ("文件已存在".equals(result)) {
			System.out.println("文件已存在");
			return;
		}

		FileInputStream fis = new FileInputStream(uploadFile); // 用于读取要上出的文件数据
		long skipLength = Long.parseLong(result); // 续传时要跳过的长度, 就是服务器中未传完文件的长度
		fis.skip(skipLength);
		byte[] buffer = new byte[1024];
		int len;
		while ((len = fis.read(buffer)) != -1)
			os.write(buffer, 0, len);
		fis.close();
		socket.close();
	}

	// 得到传入的文件路径
	private static File getFile() {
		System.out.println("请输入文件路径");
		Scanner scan = new Scanner(System.in); // Scanner对象用于从键盘接收路径信息
		while (true) {
			File file = new File(scan.nextLine()); // 建立一个File对象并从键盘接收路径
			if (!file.exists()) {
				System.out.println("文件不存在, 重新输入");
			} else if (file.isDirectory()) {
				System.out.println("暂不支持上传文件夹");
			} else
				return file;
		}
	}
}


 

服务端

package cn.itcast.tcp;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Demo3_uploadServer {

	public static void main(String[] args) throws Exception {

		ServerSocket serverSocket = new ServerSocket(30000); // 建立服务器
		while (true) {
			final Socket socket = serverSocket.accept(); // 建立Socckt
			new Thread() {
				public void run() {
					try {
						InputStream is = socket.getInputStream(); // 从客户端接收数据流对象
						OutputStream os = socket.getOutputStream(); // 写入客户端的输出流对象
						BufferedReader br = new BufferedReader(
								new InputStreamReader(is)); // 将输入的字节流转换为字符流
						PrintStream ps = new PrintStream(os); // 用于向客户端写入字符串数据

						String fileName = br.readLine();
						long fileLength = Long.parseLong(br.readLine()); // 获得文件长度
						File uploadFile = new File("E:/上传的文件", fileName); // 创建新的File对象,
																			// 用于查看文件是否已存在
						if (uploadFile.exists()
								&& uploadFile.length() == fileLength) { // 文件已存在,
																		// 退出
							ps.println("文件已存在");
							return;
						} else
							ps.println(uploadFile.length());

						String ip = socket.getInetAddress().getHostAddress();
						System.out.println(ip
								+ (uploadFile.length() == 0 ? " 开始上传: "
										: " 断点续传: ") + fileName);
						long start = System.currentTimeMillis();

						FileOutputStream fos = new FileOutputStream(uploadFile,
								true); // 接收文件, 写到本地, 可以追加
						byte[] buffer = new byte[1024];
						int len;
						while ((len = is.read(buffer)) != -1)
							// 将文件写到本地
							fos.write(buffer, 0, len);

						fos.close();
						socket.close();

						long end = System.currentTimeMillis();
						System.out.println(ip + " 上传完毕 " + fileName + "耗时 "
								+ (end - start) + " 毫秒");
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}.start();
		}
	}
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值