• 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
        );
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
      • 参数:

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

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

    • UDP Server:

      #define _WINSOCK_DEPRECATED_NO_WARNINGS
      #include 
      #include 
      #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;
      }
      
      • 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
    • UDP Client:

      #define _WINSOCK_DEPRECATED_NO_WARNINGS
      #include 
      #include 
      #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;
      }
      
      • 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

    原始套接字

    • 服务端:
      #define _WINSOCK_DEPRECATED_NO_WARNINGS
      #include 
      #include 
      #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;
      }
      
      • 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
      • 60
      • 61
      • 62
      • 63
      • 64
      • 65
      • 66
      • 67
      • 68
      • 69
      • 70
      • 71
      • 72
      • 73
      • 74
      • 75
      • 76
      • 77
      • 78
      • 79
      • 80
      • 81
      • 82
      • 83
      • 84
      • 85
      • 86
      • 87
    • 客户端:
      #define _WINSOCK_DEPRECATED_NO_WARNINGS
      #include 
      #include 
      #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
      • 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
  • 相关阅读:
    leetcode4. 寻找两个正序数组的中位数python_二分查找和递归(困难)
    【部署笔记】docker-compose 安装mongodb,一直重启 + 无法连接
    Ranger配置图片及json文件预览
    微服务学习笔记
    组合计数及补充
    mindspore训练retinanet时报错无法计算loss,停止训练
    wireshark使用host文件做IP域名解析
    WWW2024 | PromptMM:Prompt-Tuning增强的知识蒸馏助力多模态推荐系统
    骨传导耳机低频差理所当然?飞利浦A6606表示不服
    17、Mybatis获取参数值的情况3(若mapper接口方法的参数为多个时,可以手动将这些参数放入map中存储)
  • 原文地址:https://blog.csdn.net/qq_73985089/article/details/134294683