UDP-如何实现客户端与服务器端的通信(一对一、一对多、多对一、多对多之间的通信)

        Java中提供了DatagramSocket来实现这个功能

1.服务器端的程序
  • 创建Socket,监听6666端口
  • 读取来自客户端的“数据包”,创建数据包(通过DatagramPacket实现数据包的创建)
  • 接收数据包
  • 从数据包中,读取数据(通过recieve()接收数据send()发送给数据)

代码如下:

package com.ztt.udp.Demo01;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

public class UdpServer {
	public static void main(String[] args) {
		//创建Socket,监听6666端口
		try (DatagramSocket serverSocket = new DatagramSocket(6666)) {
			//读取来自客户端的数据包
			//创建数据包
			byte[] buff=new byte[1024];
			DatagramPacket packet=new DatagramPacket(buff,buff.length);
			
			//接收数据包
			serverSocket.receive(packet);
			System.out.println("读取完毕!");
			
			//从数据包中,读取数据
			byte[] data=packet.getData();
			String strFormClient=new String(data);
			System.out.println("来自客户端的信息:"+strFormClient);
			
			if("天王盖地虎".equals(strFormClient)) {
				packet.setData("宝塔镇河妖".getBytes());
			}else {
				packet.setData("哈哈哈哈哈哈哈".getBytes());
			}
			//反馈信息给客户端(发送数据包至客户端)
			serverSocket.send(packet);
			
		} catch (SocketException e) {
			
			e.printStackTrace();
		} catch (IOException e) {
			
			e.printStackTrace();
		}
	}

}
2.客户端的程序 
  • 创建socket
  • 连接指定主机的端口(客户端使用clientSocket.connect()指定远程地址和端口)
  • 创建数据包
  • 发送数据包(通过recieve()接收数据send()发送给数据)

代码如下:

package com.ztt.udp.Demo01;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

public class UdpClient {
	public static void main(String[] args) {
		//创建socket
		try (DatagramSocket clientSocket = new DatagramSocket()) {
			//连接指定主机的端口
			clientSocket.connect(InetAddress.getByName("192.168.199.112"),6666);
			
			//创建数据包
			DatagramPacket packet=new DatagramPacket(new byte[1024],1024);
			packet.setData("甜甜是甜甜".getBytes());//将数据放入数据包
			
			//发送数据包
			clientSocket.send(packet);
			
			//等待接受反馈信息(等待接收来自服务端的数据包)
			clientSocket.receive(packet);
			byte[] data=packet.getData();
			String strFormClient=new String(data);
			System.out.println("来自服务端的信息:"+strFormClient);
		
		} catch (SocketException e) {
			
			e.printStackTrace();
		} catch (UnknownHostException e) {
			
			e.printStackTrace();
		} catch (IOException e) {
			
			e.printStackTrace();
		}
	}

}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个简单的UDP通信程序,包括服务器端客户端代码,同时服务器端支持多线程通信。 首先是服务器端代码: ```c #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> #include<pthread.h> #define SERVER_PORT 8888 #define MAX_BUFFER_SIZE 1024 void *thread_recv(void *arg) { int sockfd = *(int*)arg; struct sockaddr_in client_addr; socklen_t addr_len = sizeof(client_addr); char buffer[MAX_BUFFER_SIZE]; while(1) { int n = recvfrom(sockfd, buffer, MAX_BUFFER_SIZE, 0, (struct sockaddr *)&client_addr, &addr_len); if(n < 0) { perror("recvfrom error"); continue; } buffer[n] = '\0'; printf("[Server] receive message from %s:%d: %s\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port), buffer); } close(sockfd); } int main() { // 创建 UDP socket int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if(sockfd < 0) { perror("create socket error"); exit(-1); } // 绑定监听地址 struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVER_PORT); server_addr.sin_addr.s_addr = htonl(INADDR_ANY); if(bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("bind error"); exit(-1); } // 创建多个线程接收数据 pthread_t thread_id[10]; for(int i=0; i<10; i++) { if(pthread_create(&thread_id[i], NULL, thread_recv, (void *)&sockfd) != 0) { perror("create thread error"); exit(-1); } } // 等待线程结束 for(int i=0; i<10; i++) { pthread_join(thread_id[i], NULL); } return 0; } ``` 然后是客户端代码: ```c #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<arpa/inet.h> #define SERVER_IP "127.0.0.1" #define SERVER_PORT 8888 #define MAX_BUFFER_SIZE 1024 int main() { // 创建 UDP socket int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if(sockfd < 0) { perror("create socket error"); exit(-1); } // 设置服务器地址 struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; server_addr.sin_port = htons(SERVER_PORT); inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr); // 发送数据 char buffer[MAX_BUFFER_SIZE]; int n; while(1) { printf("[Client] please input message: "); fgets(buffer, MAX_BUFFER_SIZE, stdin); buffer[strlen(buffer)-1] = '\0'; n = sendto(sockfd, buffer, strlen(buffer), 0, (struct sockaddr *)&server_addr, sizeof(server_addr)); if(n < 0) { perror("sendto error"); continue; } if(strcmp(buffer, "exit") == 0) { break; } } close(sockfd); return 0; } ``` 其中,服务器端使用了多线程来接收数据,每个线程都执行相同的函数 `thread_recv`,该函数的作用就是接收来自客户端的数据并输出到控制台。在服务器端中,我们创建了10个线程,每个线程都会阻塞在 `recvfrom` 函数上来等待数据的到来。当有数据到来时,线程将会被唤醒并处理接收到的数据。 客户端则是通过输入数据来发送给服务器,当输入 `exit` 时,程序将会退出。 注意:由于 UDP 是不可靠的传输协议,因此在发送和接收数据时,需要对 `sendto` 和 `recvfrom` 函数返回值进行判断以确保数据传输的正确性。同时,由于 UDP 是无连接的,因此客户端发送数据时需要自己指定服务器的 IP 和端口号。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值