Socket网络编程之UDP实现(C++,Rust)

以下是最基础的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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值