03.UDP套接字与原始套接字

UDP套接字

注意在UDP套接字中,要使用recvfrom和sendto

  • API:

    • recvfrom:

      接收数据包,并存储源地址(UDP)

    • 函数原型:

      int WSAAPI recvfrom(
        [in]                SOCKET   s,
        [out]               char     *buf,
        [in]                int      len,
        [in]                int      flags,
        [out]               sockaddr *from,
        [in, out, optional] int      *fromlen
      );
      
    • 参数:

      • s:标识绑定套接字的描述符
      • buf:传入数据的缓冲区
      • len:缓冲区长度
      • flags:用于修改函数调用行为
      • from:指向sockaddr结构的指针,该缓冲区中将保留源地址
      • fromlen:from指向的缓冲区大小
    • 返回值:

      如果未发生错误,recvfrom函数将返回收到的字节数

  • UDP Server:

    #define _WINSOCK_DEPRECATED_NO_WARNINGS
    #include <iostream>
    #include <WinSock2.h>
    #pragma comment(lib,"ws2_32.lib")
    
    int main() {
    	WORD wVersionRequested = MAKEWORD(2, 2);
    	WSAData lpWSAData;
    	if (WSAStartup(wVersionRequested, &lpWSAData)) {
    		std::cout << "WSAStartup Error!" << std::endl;
    		return -1;
    	}
    
    	//SOCKADDR_IN结构用于指定AF_INET地址系列的传输地址和端口
    	sockaddr_in saddr;
    	saddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    	saddr.sin_family = AF_INET;
    	saddr.sin_port = htons(50123);
    
    	SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
    	if (sock < 0) {
    		return -1;
    	}
    	char opt;
    	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    
    	int nRet = bind(sock, (sockaddr*)&saddr, sizeof(saddr));
    
    	sockaddr_in raddr;
    	int nLength = sizeof(sockaddr);
    	char szReadBuffer[50]{ 0 };
    	while (true) {
    		nRet = recvfrom(sock, szReadBuffer, 50, 0, (sockaddr*)&raddr, &nLength);
    		if (nRet < 0) {
    			return -1;
    		}
    		std::cout << "data:" << szReadBuffer << std::endl;
    		std::cout << "请输入:";
    		char szBuffer[50]{ 0 };
    		std::cin >> szBuffer;
    		sendto(sock, szBuffer, strlen(szBuffer), 0, (sockaddr*)&raddr, sizeof(sockaddr));
    	}
    	WSACleanup();
    	system("pause");
    	return 0;
    }
    
  • UDP Client:

    #define _WINSOCK_DEPRECATED_NO_WARNINGS
    #include <iostream>
    #include <WinSock2.h>
    #pragma comment(lib,"ws2_32.lib")
    
    int main() {
    
    	WORD wVersionRequested = MAKEWORD(2, 2);
    	WSAData lpWSAData;
    	WSAStartup(wVersionRequested, &lpWSAData);
    
    	sockaddr_in saddr;
    	saddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    	saddr.sin_family = AF_INET;
    	saddr.sin_port = htons(50123);
    
    	SOCKET SocClient = socket(AF_INET, SOCK_DGRAM, 0);
    	if (SocClient < 0) {
    		return -1;
    	}
    
    	char opt;
    	setsockopt(SocClient, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    
    	char szSendBuffer[50]{ 0 };
    	char szReadBuffer[50]{ 0 };
    	sockaddr_in raddr;
    	int nLength = sizeof(raddr);
    	while (true) {
    		std::cout << "请输入:";
    		std::cin >> szSendBuffer;
    		sendto(SocClient, szSendBuffer, strlen(szSendBuffer), 0, (sockaddr*)&saddr, sizeof(sockaddr));
    		recvfrom(SocClient, szReadBuffer, 50, 0, (sockaddr*)&raddr, &nLength);
    		std::cout << "Server:" << szReadBuffer << std::endl;
    	}
    	closesocket(SocClient);
    	WSACleanup();
    	system("pause");
    	return 0;
    }
    

原始套接字

  • 服务端:
    #define _WINSOCK_DEPRECATED_NO_WARNINGS
    #include <iostream>
    #include <WinSock2.h>
    #pragma comment(lib,"ws2_32.lib")
    
    typedef struct _IP_HEADER {
    	//版本信息,首部长度
    	char cVersionAndHeaderLen;
    	//服务类型
    	char vTypeOfServer;
    	//数据包长度
    	short sTotalLenOfPacket;
    	//数据包ID
    	short sPacketID;
    	//分片信息
    	short sSliceinfp;
    	//生存时间
    	char cTTL;
    	//协议类型
    	char cTypeOfProtocol;
    	//首部校验和
    	short sCheckSum;
    	//源IP地址
    	unsigned int uiSrcIP;
    	//目的IP地址
    	unsigned int uiDestIP;
    }IP_HEADER, *pIP_HEADER;
    
    typedef struct _UDP_HEADER {
    	//源端口号
    	unsigned short usSourPort;
    	//目的端口号
    	unsigned short usDestIPPort;
    	//数据包长度
    	unsigned short usLength;
    	//校验和
    	unsigned short usCheckSum;
    }UDP_HEADER, pUDP_HEADER;
    
    int main() {
    	WORD wVersionRequested = MAKEWORD(2, 2);
    	WSAData lpWSAData;
    	WSAStartup(wVersionRequested, &lpWSAData);
    
    	sockaddr_in SAddr;
    	SAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    	SAddr.sin_family = AF_INET;
    	SAddr.sin_port = htons(50123);
    	
    	SOCKET SocSrv = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
    	if (SocSrv < 0) {
    		return -1;
    	}
    
    	char opt;
    	setsockopt(SocSrv, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    
    	int nRet = bind(SocSrv, (sockaddr*)&SAddr, sizeof(SAddr));
    	if (nRet < 0) {
    		return -1;
    	}
    
    	char szReadBuffer[500]{ 0 };
    	sockaddr_in raddr;
    	int nLength = sizeof(sockaddr);
    	while (true) {
    		std::cout << "waiting......" << std::endl;
    		nRet = recvfrom(SocSrv, szReadBuffer, 500, 0, (sockaddr*)&raddr, &nLength);
    		IP_HEADER iph;
    		UDP_HEADER udph;
    		memcpy(&iph, szReadBuffer, 20);
    		memcpy(&udph, szReadBuffer + 20, 8);
    		int srcp = ntohs(udph.usSourPort);
    		in_addr ias, iad;
    		ias.s_addr = iph.uiSrcIP;
    		iad.s_addr = iph.uiDestIP;
    		char Temp[0x100]{ 0 };
    		strcpy_s(Temp, inet_ntoa(iad));
    		std::cout << "SrcIP:" << inet_ntoa(iad) << "  Port:" << ntohs(udph.usSourPort) << std::endl;
    		std::cout << "DestIP:" << inet_ntoa(iad) << "  Port:" << ntohs(udph.usDestIPPort) << std::endl;
    		std::cout << "recv data:" << szReadBuffer + 28 << std::endl;
    	}
    	closesocket(SocSrv);
    	WSACleanup();
    	system("pause");
    	return 0;
    }
    
  • 客户端:
    #define _WINSOCK_DEPRECATED_NO_WARNINGS
    #include <iostream>
    #include <WinSock2.h>
    #pragma comment(lib,"ws2_32.lib")
    
    int main() {
    
    	WORD wVerSionRequested = MAKEWORD(2, 2);
    	WSAData lpWSAData;
    	WSAStartup(wVerSionRequested, &lpWSAData);
    
    	sockaddr_in saddr;
    	saddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    	saddr.sin_family = AF_INET;
    	saddr.sin_port = htons(50123);
    	
    	SOCKET SocClient = socket(AF_INET, SOCK_DGRAM, 0);
    	if (SocClient < 0) {
    		return -1;
    	}
    
    	char opt;
    	setsockopt(SocClient, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    
    	char szSendBuffer[500]{ 0 };
    	std::cout << "input:";
    	std::cin >> szSendBuffer;
    	sendto(SocClient, szSendBuffer, strlen(szSendBuffer), 0, (sockaddr*)&s5addr, sizeof(sockaddr));	WSACleanup();
    	closesocket(SocClient);
    	WSACleanup();
    	system("pause");
    	return 0;
    }
    
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shad0w-2023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值