Chapter 3 TCP Protocol

Like UDP communication, TCP communication can realize communication between two computers. Both ends of the communication need to create socket objects.
The difference is that there are only senders and receivers in UDP, and there is no distinction between the client and the server. Data can be sent arbitrarily between computers.
The TCP communication strictly distinguishes between the client and the server. When communicating, the client must first connect to the server to achieve communication. The server cannot actively connect to the client, and the server program needs to be started in advance and wait for the connection of the client. .
Two classes are provided in JDK for implementing TCP programs, one is the ServerSocket class, which is used to represent the server side, and the other is the Socket class, which is used to represent the client side.
When communicating, first create a ServerSocket object representing the server side, which is equivalent to opening a service and waiting for the client's connection, and then creating a Socket object representing the client side to send a connection request to the server side, the server side responds to the request, and the two establish a connection to start communication. .
1.1 ServerSocket
Knowing from the previous study, when developing a TCP program, you first need to create a server-side program. JDK's java.net package provides a ServerSocket class, an instance of which can implement a server segment program. By consulting the API documentation, we can see that the ServerSocket class provides a variety of construction methods. Next, we will explain the construction methods of ServerSocket one by one.

Using this construction method, when creating a ServerSocket object, you can bind it to a specified port number (the parameter port is the port number).
Next, learn the common methods of ServerSocket, as shown in the table.

The ServerSocket object is responsible for monitoring a certain port number of a computer. After the ServerSocket object is created, it needs to continue to call the accept() method of the object to receive requests from the client. When the accept() method is executed, the server-side program will block. Until the client sends a connection request, the accept() method will return a Scoket object to communicate with the client, and the program can continue to execute downward.
1.2 Socket
explains that the ServerSocket object can realize the server program, but only the server program can not complete the communication. At this time, a client program is needed to interact with it. For this reason, JDK provides a Socket class to realize the TCP client program.
By consulting the API documentation, we can see that the Socket class also provides a variety of construction methods. Next, we will explain the common construction methods of Socket in detail.

When using this construction method to create a Socket object, it will connect to the server program running on the specified address and port according to the parameters, where the parameter host receives an IP address of a string type.

This method is similar in use to the second constructor. The parameter address is used to receive an object of type InetAddress, which is used to encapsulate an IP address.
Among the above Socket construction methods, the most commonly used is the first construction method.
Next, learn the common methods of Socket, as shown in the table.
Method declaration
function description
int getPort()
This method returns an int type object, which is the port number of the connection between the Socket object and the server
InetAddress getLocalAddress()
This method is used to obtain the local IP address bound to the Socket object, and convert the IP address The object encapsulated into InetAddress type returns
void close()
This method is used to close the Socket connection and end this communication. Before closing the socket, all input/output streams related to the socket should be closed. This is because a good program should release all resources when the execution is complete.
InputStream getInputStream()
This method returns an input stream object of type InputStream , if the object is returned by the Socket on the server side, it is used to read the data sent by the client, otherwise, it is used to read the data sent by the server
OutputStream getOutputStream()
This method returns an output stream object of type OutputStream, if the The object is returned by the Socket on the server side, which is used to send data to the client, and vice versa, used to send data to the server
Among the common methods of the Socket class, the getInputStream() and getOutStream() methods are used to obtain the input stream and output stream respectively. When the client and the server establish a connection, the data is exchanged in the form of IO stream to realize communication.
Next, a picture is used to describe the data transmission between the server and the client, as shown in the following figure.

1.3 TCP protocol implementation 1.3.1 Case code 3:

package com.itheima_04;

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

/*
 * 使用TCP协议发送数据
创建发送端Socket对象(创建连接)
获取输出流对象
发送数据
释放资源
Socket(InetAddress address, int port)
Exception in thread "main" java.net.ConnectException: Connection refused: connect

 */
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建发送端Socket对象(创建连接)
Socket s = new Socket(InetAddress.getByName("itheima"),10086);
//获取输出流对象
OutputStream os = s.getOutputStream();
//发送数据
String str = "hello tcp,im comming!!!";
os.write(str.getBytes());
//释放资源
//os.close();
s.close();
}
}
package com.itheima_04;

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

/*
 * 使用TCP协议接收数据
         创建接收端Socket对象
         监听(阻塞)
         获取输入流对象
         获取数据
         输出数据
         释放资源

         ServerSocket:接收端,服务端Socket
         ServerSocket(int port)
         Socket accept()

 */
public class ServerDemo {
public static void main(String[] args) throws IOException  {
//创建接收端Socket对象
ServerSocket ss = new ServerSocket(10086);
         //监听(阻塞)
Socket s = ss.accept();
         //获取输入流对象
InputStream is = s.getInputStream();
         //获取数据
byte[] bys = new byte[1024];
int len;//用于存储读到的字节个数
len = is.read(bys);
         //输出数据
InetAddress address = s.getInetAddress();
System.out.println("client ---> " + address.getHostName());
System.out.println(new String(bys,0,len));
         //释放资源
s.close();
//ss.close();
}
}

1.4 TCP related cases 1.4.1 Case code 4:
use TCP protocol to send data, the server converts the received data into uppercase and returns it to the client

package com.itheima_05;[/font][/align] [font=微软雅黑]
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

/*
         需求:使用TCP协议发送数据,并将接收到的数据转换成大写返回

         客户端发出数据
         服务端接收数据
         服务端转换数据
         服务端发出数据
         客户端接收数据

 */
public class ClientDemo {
public static void main(String[] args) throws IOException {
//创建客户端Socket对象
Socket s = new Socket(InetAddress.getByName("itheima"),10010);
//获取输出流对象
OutputStream os = s.getOutputStream();
//发出数据
os.write("tcp,im comming again!!!".getBytes());

//获取输入流对象
InputStream is = s.getInputStream();
byte[] bys = new byte[1024];
int len;//用于存储读取到的字节个数
//接收数据
len = is.read(bys);
//输出数据
System.out.println(new String(bys,0,len));
//释放资源
s.close();
}
}
package com.itheima_05;

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

public class ServerDemo {
public static void main(String[] args) throws IOException {
//创建服务端Socket对象
ServerSocket ss = new ServerSocket(10010);
//监听
Socket s = ss.accept();
//获取输入流对象
InputStream is = s.getInputStream();
//获取数据
byte[] bys = new byte[1024];
int len;//用于存储读取到的字节个数
len = is.read(bys);
String str = new String(bys,0,len);
//输出数据
System.out.println(str);
//转换数据
String upperStr = str.toUpperCase();
//获取输出流对象
OutputStream os = s.getOutputStream();
//返回数据(发出数据)
os.write(upperStr.getBytes());
//释放资源
s.close();
//ss.close();//服务端一般不关闭
}
}

1.4.2 Case code 5:
Client:
1. Prompt the user to enter the username and password, and send the username and password entered by the user to the server
2. Receive the result of the server verifying the username and password
Server:
1. Receive the client The sent username and password
2. If the username is not itema or the password is not 123456, write "login failed"
to the client, otherwise write the login successful to the client

package com.itheima_06;

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(InetAddress.getByName("itheima"),8888);
Socket s = new Socket("itheima",8888);
//获取用户名和密码
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入用户名:");
String username = br.readLine();
System.out.println("请输入密码:");
String password = br.readLine();
//获取输出流对象
//BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
//写出数据
out.println(username);
out.println(password);
//获取输入流对象
BufferedReader serverBr = new BufferedReader(new InputStreamReader(s.getInputStream()));
//获取服务器返回的数据
String result = serverBr.readLine();
System.out.println(result);
//释放资源
s.close();
}
}

1.4.3 Case code 6:
Encapsulate the username and password into a User class, provide the corresponding constructor and getter/setter methods
Create a new UserDB class to define a collection, and add the following User object
new User("zhangsan" ,"123456");
new User("lisi","654321");
new User("itheima","itheima");
new User("admin","password");
Client:
1. Prompt the user for input Username and password, send the username and password entered by the user to the server
2. Receive the result of the server verifying the username and password

Server:

  1. The server encapsulates the username and password sent by the client into a User object
  2. If this User object is included in the collection, the client should write "login successful",
    otherwise write "login failed" to the client
package com.itheima_06;[/font][/align] [font=微软雅黑]
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerTest {
public static void main(String[] args) throws IOException {
//创建服务器端Socket对象
ServerSocket ss = new ServerSocket(8888);
//监听
Socket s = ss.accept();
//获取输入流对象
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//获取用户名和密码
String username = br.readLine();
String password = br.readLine();
//判断用户名和密码是否正确
boolean flag = false;
if("itheima".equals(username) && "123456".equals(password)) {
flag = true;
}
//获取输出流对象
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
//返回判断信息
if(flag) {
out.println("登陆成功");
}
else {
out.println("登陆失败");
}
//释放资源
s.close();
//ss.close();//服务器一般不关闭
}
}
package com.itheima_07;

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("itheima",8888);
//获取用户名和密码
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入用户名:");
String username = br.readLine();
System.out.println("请输入密码:");
String password = br.readLine();
//获取输出流对象
PrintWriter out = new PrintWriter(s.getOutputStream(),true);
//写出数据
out.println(username);
out.println(password);
//获取输入流对象
BufferedReader serverBr = new BufferedReader(new InputStreamReader(s.getInputStream()));
//获取服务器返回的数据
String result = serverBr.readLine();
System.out.println(result);
//释放资源
s.close();
}
}
package com.itheima_07;

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(8888);
//监听
Socket s = ss.accept();
//获取输入流对象
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
//获取用户名和密码
String username = br.readLine();
String password = br.readLine();
//判断用户名和密码是否正确
boolean flag = false;
/*if("itheima".equals(username) && "123456".equals(password)) {
flag = true;
}*/
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();//服务器一般不关闭
}
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324853275&siteId=291194637