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