TCP
实现A(客户端)向B(服务器)发送消息,B向A回复消息
首先
A->B(第一次发消息)
因为是第一次发送消息,所以要先建立连接,则需要B的IP和B的端口号
同时,B会在指定的端口监听,监听到了先进行连接(三次握手连接,若是连接不上,A就会报错)
连接成功后,B再通过A发给B的Socket读取第一次发送的消息
B->A
因为是第一发消息成功,保留了socket,所以后续就不需要再连接,直接进行发送和接收
在后续的通信中,两边都创建一个只接收消息线程不停的接收消息(不用创建发送消息的线程),
也就是说,A向B发送消息,B接收消息的线程接收到了,然后B又向A回复消息,A接收消息的线程接收到了,依次循环
注意:A与B不再进行通信时,需要关闭socket(socket.close())
上代码:
服务端
package text;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Server{
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(888);
//监听端口
Socket socket = server.accept();
InputStreamReader reader
= new InputStreamReader(socket.getInputStream());
BufferedReader buffer_reader=new BufferedReader(reader);
PrintWriter writer=new PrintWriter(socket.getOutputStream());
//读取客户端发来的信息
String request = buffer_reader.readLine();
System. out .println("Client say:" + request);
String line="Hello,too!";
writer.println(line);
writer.flush();
writer.close();
buffer_reader.close();
//关闭socket
socket.close();
server.close();
}
}
客户端
package text;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class Client {
public static void main(String[] args) throws UnknownHostException, IOException {
//创建客户端发送socket 服务端IP和服务端Port
Socket socket = new Socket("127.0.0.1",888);
InputStreamReader reader = new InputStreamReader(socket.getInputStream());
BufferedReader buffer_reader = new BufferedReader(reader);
PrintWriter writer = new PrintWriter(socket.getOutputStream());
String readline = "Hello!";
writer.println(readline);
writer.flush();
//读取服务端回复的消息
String response = buffer_reader.readLine();
System. out .println("Server say:"+ response);
writer.close();
buffer_reader.close();
socket.close();
}
}
-------------------------------------------------分割线------------------------------------------------------------------
UDP
A(客户端)向B(服务端)发送消息,B向A回复消息
首先
A->B
A要有B的IP和B的端口号,A实例化一个发送消息的socket,不需要绑定端口和IP,
但是数据报Paceket里面要写上B的端口和B的IP
系统会自动找空闲端口将A的找到的这个发送消息的空闲端口信息和A的IP封装到socket,通过socket发送出去B->A
B接收到这个数据报(根据UDP数据报协议,数据报里面包含了源IP和源端口号以及目的地址和目的端口,以及内容)
通过DatagramPacket.getSocketAddress()方法解析出A的SocketAddress(也就是A的套接字地址)
数据报格式:
继续上代码:
客户端
package text;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Client {
public static void main(String[] args) {
try {
// 创建发送方的套接字,IP默认为本地,端口号随机
DatagramSocket sendSocket = new DatagramSocket();
// 确 定要发送的消息:
String mes = "你好!接收方!";
// 由于数据报的数据是以字符数组传的形式存储的,所以传转数据
byte[] buf = mes.getBytes();
// 确定发送方的IP地址及端口号,地址为本地机器地址
int port = 8888;
InetAddress ip = InetAddress. getLocalHost ();
// 创建发送类型的数据报:
DatagramPacket sendPacket = new DatagramPacket(buf, buf.length, ip, port);
// 通过套接字发送数据:
sendSocket.send(sendPacket);
// 确定接受反馈数据的缓冲存储 器,即存储数据的字节数组
byte[] getBuf = new byte[1024];
// 创建接受类型的数据报
DatagramPacket getPacket = new DatagramPacket(getBuf, getBuf.length);
// 通过套接字接受数据
sendSocket.receive(getPacket);
// 解析反馈的消息,并打印
String backMes = new String(getBuf, 0, getPacket.getLength());
System.out.println("接受方返回的消息:" + backMes);
// 关闭套接字
sendSocket.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
服务端
package text;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketAddress;
public class Server {
public static void main(String[] args) {
try {
InetAddress ip = InetAddress. getLocalHost ();
int port = 8888;
// 创建接收方的套接字,并制定端口号和IP地址
DatagramSocket getSocket = new DatagramSocket(port, ip);
// 确定数据报接受的数据的数组大小
byte[] buf = new byte[1024];
// 创建接受类型的数据报,数据将 存储在buf中
DatagramPacket getPacket = new DatagramPacket(buf, buf.length);
// 通过套接字接收数据
getSocket.receive(getPacket);
String getMes= new String(buf,0, getPacket.getLength());
System.out.println("对方发送的消息:" + getMes);
InetAddress sendIP = getPacket.getAddress();
int sendPort = getPacket.getPort();
System.out.println("对方的地址是:" + sendIP.getHostAddress() + ":" + sendPort);
// 通过数据报得到发送方的套接字地址
SocketAddress sendAddress = getPacket.getSocketAddress();
String feedback = "接收方说:我收到了!";
byte[] backBuf = feedback.getBytes();
DatagramPacket sendPacket = new DatagramPacket(backBuf, backBuf.length, sendAddress);
getSocket.send(sendPacket);
getSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
在此基础上,我自己在借鉴网上资料,自己编写了一个基于TCP协议的聊天室,能够简单实现登录、注册、群聊、私聊、历史消息查看,源码下载地址 https://download.csdn.net/download/qq_37513473/10509044
另附一下数据库表
user表
message表
以上为我自己对TCP和UDP通信使用方法的理解,若有不足之处欢迎大家多多指教。