------- android培训、java培训、期待与您交流! ----------
TCP特点
1. 面向连接,客户端和服务端必须先建立连接
2. 客户端用Socket来向服务端发出请求,服务端用ServerSocket来获得客户端请求的Socket
3. 通过socket中的getOutputStream和getInputStream来进行收发数据
4. 需要经过三次握手建立连接,所以数据传输是安全的
UDP和TCP总结
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();
}
}
}