Abstract: for the preparation of TCP protocol network programs, the key lies in the proficient use of ServerSocket sockets. All information transmission in TCP communication is carried out by relying on the input and output streams of the ServerSocket class.
This article is shared from the HUAWEI cloud community " Java uses TCP protocol to achieve client-server communication [with communication source code] ", author: Gray Little Ape.
TCP protocol concept
We know that TCP is a reliable and not secure network protocol. It can ensure that the data can be delivered accurately when it is sent from one end to the other, and the sequence of the arriving data is the same as the sequence when it is sent. Therefore, when performing TCP protocol communication, we should first ensure that the connection between the client and the server is smooth.
The writing of the TCP protocol program is still implemented by the socket Socket class, and there is a primary and secondary distinction between the two programs that use the TCP protocol to communicate, that is, one is the server program and the other is the client. End of the program. Therefore, the functions and writing of the two are also slightly different. The following figure is a schematic diagram of the communication between the server and the client:
The above is a schematic diagram of the process of establishing a connection between the client and the server in the TCP protocol. The key roles in this are the server-side socket ServerSocket and the client-side socket Socket. The server and the client are established through these two sockets, so that the functions in them are used for data communication.
There are a lot of things to pay attention to in the ServerSocket class. Next, Big Bad Wolf will share with you the specific usage of the ServerSocket class:
ServerSocket class
The ServerSocket class exists in the package, which represents the socket on the server side. This class needs to be imported first when using it. We also know that the main function of the ServerSocket class is to wait for clients from the network through the specified port Request and connect.
worth noting: server socket can only connect with one client socket at a time, so if there are multiple clients sending connection requests at the same time, the server socket will store the requested client in Go to the queue, and then take out a socket to connect with the socket established by the server, but the client sockets that the server can accommodate are not unlimited. When the number of requested connections is greater than the maximum capacity, so many The outgoing request will be rejected. Generally speaking, the default size of the queue is 50.
The construction method of the ServerSocket class usually throws an IOException, which can be in the following forms:
• ServerSocket(): Create an unbound server socket
• ServerSocket (inr port): Create a server socket bound to a specific port
• ServerSocket(int port, int backlog): Use the specified backlog to create a server socket and bind it to the specified server port,
• ServerSocket (int port, int backlog, InetAddress bindAddress): Use the specified port to listen to the backlog and create a server to bind to the local IP address. This situation applies to the situation where there are multiple network cards and multiple IP addresses on the computer. The user can clearly specify which network card or IP address the ServerSocket waits for the user's connection request.
The following are some commonly used methods in the ServerSocket class:
After understanding the basic methods of the ServerSocket class, it is the question of how to connect the client and the server.
On the server side, we can call the accpet() method of the ServerSocket class to establish a connection with the client requesting a connection. At this time, a Socket object connected to the client will be returned. At this time, the connection is actually successful, just use the getInetAddress() method. The IP address of the requesting client can be obtained.
For how to communicate between client and server data, it is necessary to use the input stream and output stream of the data. The Socket object on the server side uses the output stream obtained by the getOutputStream() method, and the Socket object pointing to the client uses getInputStream( The input stream obtained by the) method. In this way, a process of sending data from the server to the client is same is true for 1613320812da05. The Socket object on the client side uses the output stream obtained by the getOutputStream() method, and the Socket object pointing to the server side is obtained by the getInputStream() method. Input stream. So as to realize the process of sending data from the client to the server.
Note: The accpet() method will block the continued execution of the thread. If the client's call is not received on the corresponding interface, the program will stay here until the client's call is obtained. The execution will continue, but if The server does not receive the call request from the client, and the accpet() method is not blocked, then usually the program has a problem. Generally speaking, a port number that has been occupied by other programs may be used, causing the ServerSocket to fail. The binding is successful! In this case, you can try to change to a new port number.
After understanding the communication process of the TCP protocol, the next step is to write the TCP communication program!
In network communication, if only the client is required to send information to the server, the behavior that does not require the server to feed back information to the client is called "one-way communication", and the process of requiring the client and server to communicate with each other is called "two-way communication". Two-way communication is just one more process of sending messages from the server to the client than one-way communication.
Next is the preparation of server-side and client-side programs:
Server-side program
package server_1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class MyTcp {
private ServerSocket server; //设置服务器套接字
private Socket client; //设置客户端套接字
//连接客户端函数
void getServer()
{
try {
server = new ServerSocket(1100); //建立服务器 端口为1100
System.out.println("服务器建立成功!正在等待连接......");
client = server.accept(); //调用服务器函数对客户端进行连接
System.out.println("客户端连接成功!ip为:" + client.getInetAddress()); //返回客户端IP
getClientMessage(); //调用信息传输和接收函数
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
void getClientMessage()
{
try {
while (true) {
InputStream is = client.getInputStream(); //获取到客户端的输入流
byte[] b = new byte[1024]; //定义字节数组
int len = is.read(b); //由于信息的传输是以二进制的形式,所以要以二进制的形式进行数据的读取
String data = new String(b, 0,len);
System.out.println("客户端发来消息:" + data);
//定义发送给客户端的输出流
OutputStream put = client.getOutputStream();
String putText = "我已经收到!欢迎你!";
put.write(putText.getBytes()); //将输出流信息以二进制的形式进行写入
}
} catch (Exception e) {
// TODO: handle exception
}
try {
//判断客户端字节流不是空,则关闭客户端
if (server != null) {
server.close();
}
} catch (Exception e) {
// TODO: handle exception
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
MyTcp myTcp = new MyTcp(); //调用该类生成对象
myTcp.getServer(); //调用方法
}
}
Client program
package client_1;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class MyClient {
private Socket client; //定义客户端套接字
//建立客户端函数
void getClient()
{
try {
client = new Socket("127.0.0.1", 1100); //建立客户端,使用的IP为127.0.0.1,端口和服务器一样为1100
System.out.println("客户端建立成功!");
setClientMessage(); //调用客户端信息写入函数
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//定义客户端信息写入函数
void setClientMessage()
{
try {
OutputStream pt = client.getOutputStream(); //建立客户端信息输出流
String printText = "服务器你好!我是客户端!";
pt.write(printText.getBytes()); //以二进制的形式将信息进行输出
InputStream input = client.getInputStream(); //建立客户端信息输入流
byte [] b = new byte[1024]; //定义字节数组
int len = input.read(b); //读取接收的二进制信息流
String data = new String(b, 0,len);
System.out.println("收到服务器消息:" + data);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
//如果客户端信息流不为空,则说明客户端已经建立连接,关闭客户端
if (client != null) {
client.close();
}
} catch (Exception e) {
// TODO: handle exception
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
//生成客户端类对象
MyClient myClient = new MyClient();
myClient.getClient();
}
}
also pay attention to: After the client and server are successfully set up, the server should be opened to wait for the connection, and then the client should be opened to connect. Similarly, when closing, the client should be closed first, and then the server should be closed.
Take the above program as an example:
Open the server and wait for the client to connect
Open the connection between the client and the server successfully, and realize two-way communication:
Note: When multiple network applications are installed on a machine, it is likely that the specified port has been occupied, and you may even encounter a situation where a program that was running well before suddenly gets stuck. This situation is likely to be The port is occupied by another program. At this time, you can run netstat-help to help you live. You can use the command netstat-an to view the port used by the program.
Click to follow and learn about Huawei Cloud's fresh technology for the first time~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。