以下是最基础的UDP服务端与客户端源代码,实现客户端发送数据,服务器接收数据的功能。与TCP的区别在于客户端与服务端无需经过三次握手建立连接,可直接在相应端口收发数据。且内部没有流控,重发等机制进行可靠性保证,协议实现相对TCP简单。可简单认为是带有端口信息的IP数据报。
一、C++实现
【1】服务端源代码(Windows)
#include "stdafx.h"
#include<WinSock2.h>
#include<iostream>
using namespace std;
#pragma comment(lib,"ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
//初始化socket资源
WSADATA WSAData;
WORD sockVersion=MAKEWORD(2,2);
if(WSAStartup(sockVersion,&WSAData)!=0)
return 0;
SOCKET serSocket = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); //创建服务器socket
if(INVALID_SOCKET==serSocket)
{
cout<<"socket error!";
return 0;
}
//设置传输协议、端口以及目的地址
sockaddr_in serAddr;
serAddr.sin_family=AF_INET;
serAddr.sin_port=htons(8888);
serAddr.sin_addr.S_un.S_addr=INADDR_ANY;
if(bind(serSocket,(sockaddr*)&serAddr,sizeof(serAddr))==SOCKET_ERROR) //将socket绑定地址
{
cout<<"bind error";
closesocket(serSocket);
return 0;
}
sockaddr_in clientAddr;
int iAddrlen=sizeof(clientAddr);
char buff[1024]; //建立接收缓存字节数组
while(true)
{
memset(buff,0,1024); //清空接收缓存数组
//开始接收数据
int len=recvfrom(serSocket,buff,1024,0,(sockaddr*)&clientAddr,&iAddrlen);
if(len>0)
{
cout<<"客户端地址:"<<inet_ntoa(clientAddr.sin_addr)<<endl;
cout<<buff;
// sendto(serSocket,buff,1024,0,(sockaddr*)&clientAddr,iAddrlen);
}
}
closesocket(serSocket); //关闭socket
WSACleanup();
return 0;
}
【2】客户端源代码
#include "stdafx.h"
#include<WinSock2.h>
#include<iostream>
using namespace std;
#pragma comment(lib,"ws2_32.lib")
int _tmain(int argc, _TCHAR* argv[])
{
WSADATA WSAData;
WORD sockVersion=MAKEWORD(2,2);
if(WSAStartup(sockVersion,&WSAData)!=0)
return 0;
SOCKET clientSocket = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(INVALID_SOCKET==clientSocket)
{
cout<<"socket error!";
return 0;
}
sockaddr_in dstAddr;
dstAddr.sin_family=AF_INET;
dstAddr.sin_port=htons(8888);
dstAddr.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
const char* sendData="来自客户端的数据包。";
sendto(clientSocket,sendData,strlen(sendData),0,(sockaddr*)&dstAddr,sizeof(dstAddr));
closesocket(clientSocket);
WSACleanup();
return 0;
}
运行结果:
二、Rust实现
【1】服务端代码:
use std::net::UdpSocket;
fn main() {
let socket = UdpSocket::bind("0.0.0.0:8888").unwrap();
let mut buf = [0; 65535];
loop {
let (amt, src) = socket.recv_from(&mut buf).unwrap();
println!("received {} bytes from: {:?}", amt, src);
}
}
【2】客户端代码:
use std::net::UdpSocket;
use std::thread;
fn main() {
let socket = UdpSocket::bind("0.0.0.0:22222").unwrap();
let buf = [1u8; 60000];
let mut count = 1;
loop {
socket.send_to(&buf[0..count], "192.168.2.237:8888").unwrap();
count = count + 1;
if count == 2 {
break;
}
}
thread::sleep_ms(1000);
}