TCP协议学习总结

一、TCP协议概念
TCP(Transmission Control Protocol 传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内另一个重要的传输协议。在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换;TCP协议是在通信的两台设备之间建立连接通道,对传输的数据大小没有限制,但是因为建立连接,可靠一些,但是速度会慢一些。TCP协议又称为三次握手协议,因为建立过程有三步,发送请求、获取反馈、建立连接。
二、TCP连接管理机制
TCP需要经过三次握手建立连接
第一次: 客户端 - - > 服务器 此时服务器知道了客户端要建立连接了
第二次: 客户端 < - - 服务器 此时客户端知道服务器收到连接请求了
第三次: 客户端 - - > 服务器 此时服务器知道客户端收到了自己的回应
到这里, 就可以认为客户端与服务器已经建立了连接。
三、ServerSocket与Socket类的使用
JDK中提供了两个类用于实现TCP程序,一个是ServerSocket类,用于表示服务器端,一个是Socket类,用于表示客户端。通信时,首先创建代表服务器端的ServerSocket对象,该对象相当于开启一个服务,并等待客户端的连接,然后创建代表客户端的Socket对象向服务器端发出连接请求,服务器端响应请求,两者建立连接开始通信。
(1)ServerSocket类
JDK的java.net包中提供了一个ServerSocket类,该类的实例对象可以实现一个服务器段的程序。通过查阅API文档可知,ServerSocket类提供了多种构造方法,接下来就对ServerSocket的构造方法进行逐一地讲解。
在这里插入图片描述
使用该构造方法在创建ServerSocket对象时,就可以将其绑定到一个指定的端口号上(参数port就是端口号)。
接下来学习一下ServerSocket的常用方法,如表所示。
在这里插入图片描述
ServerSocket对象负责监听某台计算机的某个端口号,在创建ServerSocket对象后,需要继续调用该对象的accept()方法,接收来自客户端的请求。当执行了accept()方法之后,服务器端程序会发生阻塞,直到客户端发出连接请求,accept()方法才会返回一个Scoket对象用于和客户端实现通信,程序才能继续向下执行。
(2)Socket类
JDK提供了一个Socket类,用于实现TCP客户端程序
通过查阅API文档可知Socket类同样提供了多种构造方法,接下来就对Socket的常用构造方法进行详细讲解。
在这里插入图片描述
使用该构造方法在创建Socket对象时,会根据参数去连接在指定地址和端口上运行的服务器程序,其中参数host接收的是一个字符串类型的IP地址。
在这里插入图片描述
该方法在使用上与第二个构造方法类似,参数address用于接收一个InetAddress类型的对象,该对象用于封装一个IP地址。
在以上Socket的构造方法中,最常用的是第一个构造方法。
接下来学习一下Socket的常用方法,如表所示。
在这里插入图片描述
在Socket类的常用方法中,getInputStream()和getOutStream()方法分别用于获取输入流和输出流。当客户端和服务端建立连接后,数据是以IO流的形式进行交互的,从而实现通信。
接下来通过一张图来描述服务器端和客户端的数据传输,如下图所示。

在这里插入图片描述
四、TCP的使用案例
(1)客户端实现代码

package TCP2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
/*
 * 模拟用户登录
 */
public class ClientTest {
	public static void main(String[] args) throws IOException {	
		//创建客户端Socket对象
		Socket s = new Socket("QX",8080);	
		//获取用户名和密码
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		System.out.println("请输入用户名:");
		String username = br.readLine();
		System.out.println("请输入密码:");
		String password = br.readLine();	
		//获取输出流对象
		PrintWriter pw = new PrintWriter(s.getOutputStream(),true);
		//写出数据
		pw.println(username);
		pw.println(password);
		//获取输入流对象
		BufferedReader serverBr = new BufferedReader(new InputStreamReader(s.getInputStream()));
		//获取服务器返回的数据
		String result = serverBr.readLine();
		System.out.println(result);
		//释放资源
		s.close();	
	}
}

(2)服务端实现代码

package TCP2;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
public class ServerTest {
	public static void main(String[] args) throws IOException {
		//创建服务器端Socket对象
		ServerSocket ss = new ServerSocket(8080);
		//监听
		Socket s = ss.accept();
		//获取输入流对象
		BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
		//获取用户名和密码
		String username = br.readLine();
		String password = br.readLine();
		//判断用户名和密码是否正确
		boolean flag = false;
					
		List<User> users = UserDB.getUsers();
		User user = new User(username,password);
		if(users.contains(user)) {
			flag = true; //匹配成功
		}
		//获取输出流对象
		PrintWriter out = new PrintWriter(s.getOutputStream(),true);
		//返回判断信息
		if(flag) {
			out.println("登陆成功");
		}
		else {
			out.println("登陆失败");
		}
		//释放资源
		s.close();
		//ss.close();//服务器一般不关闭
	}
}

(3)创建类模拟用户表

package TCP2;
public class User {
	private String username;
	private String password;
	public User() {
		super();
	}
	public User(String username, String password) {
		super();
		this.username = username;
		this.password = password;
	}	
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		User other = (User) obj;
		if (password == null) {
			if (other.password != null)
				return false;
		} else if (!password.equals(other.password))
			return false;
		if (username == null) {
			if (other.username != null)
				return false;
		} else if (!username.equals(other.username))
			return false;
		return true;
	}	
	
}

(4)创建类模拟数据表数据

package TCP2;
import java.util.ArrayList;
import java.util.List;

public class UserDB {	
	private static List users = new ArrayList<User>();
	static{
		users.add(new User("张三","123"));
		users.add(new User("李四","321"));
		users.add(new User("王五","123"));
		users.add(new User("赵六","321"));	
	}
	public  static List<User> getUsers(){
		return users;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值