TCP和UDP实现简单一对一通信

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通信使用方法的理解,若有不足之处欢迎大家多多指教。

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值