基本概述
什么是TCP?
传输控制协议,面向连接的、可靠的、基于字节流的传输层通信协议
TCP通信原理
客户端和服务器通信
客户端向服务器发送消息:询问是否收到
服务器回复客户端:我收到了,你收到了吗
客户端回复服务器:我也收到了
就像两个人打电话,至少需要3句话,才能确定两个人都能收到对方的消息
TCP通信步骤:
1、经过三次握手,确定计算机之间可以连接
2、建立对应的双向的字节流通道,进行数据的传输
a.客户端向服务器端传输数据:客户端输出,服务器端读取
b.服务器端向客户端传输数据:服务器端输出,客户端读取
常用方法:
① ServerSocket(int port) 通过指定端口创建服务器对象。
② accept() 侦听并接收指定端口的客户端的连接。
③ Socket(InetAddress address, int port)
向指定的ip地址与端口号发送数据。
④ getInputStream() 返回输入流
⑤ getOutputStream() 返回输出流
⑥ shutdownInput() /shutdownOutput() 禁用输入/出流
TCP的特点:面向连接 、可靠的 、基于字节流的传输层通信协议,相对于UDP来说,传输速度慢
简单模拟聊天室
public class TCP客户端 {
public static void main(String[] args) throws IOException {
Socket sc = new Socket(InetAddress.getLocalHost(), 9000);//指定服务器端ip,发送端口
Scanner scanner = new Scanner(System.in);
//向服务器端输出的流
OutputStream os = sc.getOutputStream();
System.out.println("发送给服务器端的消息:");
String xx = scanner.nextLine();
//写入输出
os.write(xx.getBytes());
//接收信息
InputStream in = sc.getInputStream();
byte[] b = new byte[1024];
int value = in.read(b);
System.out.println("来自服务器端的消息:");
System.out.println(new String(b, 0, value));
//关闭资源
sc.close();
}
}
public class TCP服务器端 {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(9000);
System.out.println("等待客户端的连接。。。。");
Socket s = ss.accept();
System.out.println("已经连接上了。。。客户端。。");
//已经连接成功,经过了三次握手,建立了流通道
//读取客户端传递过来的数据
//获取建立的流通道中的输入流
InputStream in = s.getInputStream();
byte[] b = new byte[1024];
int value=0;
System.out.println("来自客户端的消息为:");
value=in.read(b);
System.out.println(new String(b, 0, value));
//获取输出流
OutputStream out = s.getOutputStream();
Scanner scanner = new Scanner(System.in);
String xx = scanner.nextLine();
out.write(xx.getBytes());
//关闭资源
ss.close();
}
}
带缓冲区的聊天室
public class TCP客户端带缓冲区 {
public static void main(String[] args) throws IOException {
Socket sc = new Socket(InetAddress.getLocalHost(), 9000);
//向服务器端传数据
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sc.getOutputStream()));
System.out.println("请输入发给服务器端的内容:");
//BufferedReader readLine 读取一行字符串 因为是文字交流 就可以用字符流
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String input = br.readLine();//遇到换行才会结束输入
//向服务器端写入数据
bw.write(input);
bw.newLine();//换行
//刷新缓冲区
bw.flush();
//读取从服务器反馈来的信息
BufferedReader brserver = new BufferedReader(new InputStreamReader(sc.getInputStream()));
String msg = brserver.readLine();
System.out.println("从服务器端反馈来的信息:"+msg);
}
}
public class TCP服务器端带缓冲区 {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(9000);//服务器端socket 监听9000端口
//接收数据
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String msg = br.readLine();
System.out.println("从客户端传来的信息:"+msg);
System.out.println("请输入发送给客户端的信息:");
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bw.write(input);
bw.newLine();
//刷新缓冲区
bw.flush();
//关闭资源
ss.close();
}
}
整理版
public class 客户端 {
public static void main(String[] args) throws Exception {
Socket sc=new Socket(InetAddress.getLocalHost(),9000);
//向服务器端传输数据
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(sc.getOutputStream()));
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
BufferedReader brFromServer=new BufferedReader(new InputStreamReader(sc.getInputStream()));
while (true) {
System.out.println("请输入您要发送给服务器端的信息:");
//BufferedReader readLine
String input = br.readLine();
//向服务器端写入数据
bw.write(input);
//换行符
bw.newLine();
//刷新缓冲区
bw.flush();
//中断
if(input.equalsIgnoreCase("exit")) {
break;
}
//读取从服务器端反馈的信息
String msg = brFromServer.readLine();
System.out.println("从服务器端反馈的信息为:" + msg);
}
//关闭了
sc.close();
}
}
public class 服务器端 {
public static void main(String[] args) throws Exception {
ServerSocket ss=new ServerSocket(9000);
Scanner sc = new Scanner(System.in);
boolean flag=true;
while (flag) {
//等待客户端的连接
Socket s = ss.accept();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
while (true) {
//接收从客户端发来的数据
String msg = br.readLine();
System.out.println("从客户端发送来的信息为:" + msg);
//中断
if (msg.equalsIgnoreCase("exit")) {
break;
}
//服务器端 在控制上输入反馈信息
System.out.println("请输入您要反馈给客户端的信息:");
String input = sc.nextLine();
//将反馈信息发送给客户端
bw.write(input);
bw.newLine();
bw.flush();
}
//关闭
s.close();
}
//关闭资源
ss.close();
}
}
TCP与UDP的区别
TCP 面向连接的,通过字节流的通道进行数据传输,没有传输限制,可靠,但是传输速度慢
UDP 面向无连接的 ,通过数据报包进行传输,最大传输不能超过64k,不可靠,传输速度快
文件上传(文件传输)
(1) 客户端的Socket
① 客户端的程序需要将文件读取到程序中,并且向服务器端写入
(2) 服务器的ServerSocket
① 读取客户端的写入的内容 并且向硬盘上的某个位置写入
public class 文件上传客户端 {
public static void main(String[] args) throws IOException {
Socket sc = new Socket(InetAddress.getLocalHost(), 9000);//客户端socket
FileInputStream fileInputStream = new FileInputStream(new File("C:\\Users\\yang\\Desktop\\super.zip"));//文件输入流
OutputStream os = sc.getOutputStream();
int value = 0;
byte[] b = new byte[1024];
while ((value=fileInputStream.read(b))!=-1) {
os.write(b, 0, value);
}
//关闭资源
sc.close();
}
}
public class 文件上传服务器端 {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(9000);
Socket s = ss.accept();
//文件输出
FileOutputStream fileOutputStream = new FileOutputStream(new File("upload\\1.zip"));
//读入文件
InputStream in = s.getInputStream();
byte[] b = new byte[1024];
int value = 0;
while ((value=in.read(b))!=-1) {
fileOutputStream.write(b, 0, value);
}
//关闭资源
ss.close();
}
}