// UdpDemo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <Winsock2.h>
#include <WS2tcpip.h>//inet_ntop, inet_pton
#pragma comment(lib, "WS2_32.lib")
#define BUF_SIZE 64
int main()
{
int ret;
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
ret = WSAStartup(wVersionRequested, &wsaData);
if (ret != 0) {
printf("WSAStartup() called failed!\n");
return -1;
}
else {
printf("WSAStartup() called success!\n");
}
if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
//若不是所请求的版本号2.2,则终止WinSock库的使用
WSACleanup();
return -1;
}
/*
AF 表示ADDRESS FAMILY 地址族
PF 表示PROTOCL FAMILY 协议族
所以在windows中AF_INET与PF_INET完全一样
而在Unix/Linux系统中,在不同的版本中这两者有微小差别,对于BSD,是AF,对于POSIX是PF
#define PF_INET AF_INET
#define SOCK_STREAM 1 // stream socket
#define SOCK_DGRAM 2 // datagram socket
#define SOCK_RAW 3 // raw-protocol interface
#define SOCK_RDM 4 // reliably-delivered message
#define SOCK_SEQPACKET 5 // sequenced packet stream
typedef enum {
#if(_WIN32_WINNT >= 0x0501)
IPPROTO_HOPOPTS = 0, // IPv6 Hop-by-Hop options
#endif//(_WIN32_WINNT >= 0x0501)
IPPROTO_ICMP = 1,
IPPROTO_IGMP = 2,
IPPROTO_GGP = 3,
#if(_WIN32_WINNT >= 0x0501)
IPPROTO_IPV4 = 4,
#endif//(_WIN32_WINNT >= 0x0501)
#if(_WIN32_WINNT >= 0x0600)
IPPROTO_ST = 5,
#endif//(_WIN32_WINNT >= 0x0600)
IPPROTO_TCP = 6,
#if(_WIN32_WINNT >= 0x0600)
IPPROTO_CBT = 7,
IPPROTO_EGP = 8,
IPPROTO_IGP = 9,
#endif//(_WIN32_WINNT >= 0x0600)
IPPROTO_PUP = 12,
IPPROTO_UDP = 17,
IPPROTO_IDP = 22,
#if(_WIN32_WINNT >= 0x0600)
IPPROTO_RDP = 27,
#endif//(_WIN32_WINNT >= 0x0600)
#if(_WIN32_WINNT >= 0x0501)
IPPROTO_IPV6 = 41, // IPv6 header
IPPROTO_ROUTING = 43, // IPv6 Routing header
IPPROTO_FRAGMENT = 44, // IPv6 fragmentation header
IPPROTO_ESP = 50, // encapsulating security payload
IPPROTO_AH = 51, // authentication header
IPPROTO_ICMPV6 = 58, // ICMPv6
IPPROTO_NONE = 59, // IPv6 no next header
IPPROTO_DSTOPTS = 60, // IPv6 Destination options
#endif//(_WIN32_WINNT >= 0x0501)
IPPROTO_ND = 77,
#if(_WIN32_WINNT >= 0x0501)
IPPROTO_ICLFXBM = 78,
#endif//(_WIN32_WINNT >= 0x0501)
#if(_WIN32_WINNT >= 0x0600)
IPPROTO_PIM = 103,
IPPROTO_PGM = 113,
IPPROTO_L2TP = 115,
IPPROTO_SCTP = 132,
#endif//(_WIN32_WINNT >= 0x0600)
IPPROTO_RAW = 255,
IPPROTO_MAX = 256,
//
// These are reserved for internal use by Windows.
//
IPPROTO_RESERVED_RAW = 257,
IPPROTO_RESERVED_IPSEC = 258,
IPPROTO_RESERVED_IPSECOFFLOAD = 259,
IPPROTO_RESERVED_WNV = 260,
IPPROTO_RESERVED_MAX = 261
} IPPROTO, *PIPROTO;
*/
SOCKET udpSocket = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
/*
//Structure used to store most addresses.
typedef struct sockaddr {
#if (_WIN32_WINNT < 0x0600)
u_short sa_family;
#else
ADDRESS_FAMILY sa_family; // Address family.
#endif //(_WIN32_WINNT < 0x0600)
CHAR sa_data[14]; // Up to 14 bytes of direct address.
} SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;
//IPv4 Socket address, Internet style
typedef struct sockaddr_in {
#if(_WIN32_WINNT < 0x0600)
short sin_family;
#else //(_WIN32_WINNT < 0x0600)
ADDRESS_FAMILY sin_family;
#endif //(_WIN32_WINNT < 0x0600)
USHORT sin_port;
IN_ADDR sin_addr;
CHAR sin_zero[8];
} SOCKADDR_IN, *PSOCKADDR_IN;
可以看出sockaddr是通用的,而sockaddr_in是针对Ipv4的
*/
sockaddr_in sockAddr;
/*
Error C4996 'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings
sockAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
IP地址转换函数,可以在将IP地址在“点分十进制”和“二进制整数”之间转换
inet_pton:将“点分十进制” -> “二进制整数”
int inet_pton(
int af, //地址簇
const char *src,//源地址
void *dst //目的地址
);
*/
inet_pton(PF_INET, "127.0.0.1", &sockAddr.sin_addr.S_un.S_addr);
sockAddr.sin_family = PF_INET;
sockAddr.sin_port = htons(7777);
bind(udpSocket, (SOCKADDR*)&sockAddr, sizeof(sockAddr));
sockaddr_in otherAddr;
int addrLen = sizeof(otherAddr);
char buf[MAXBYTE] = { 0 };
recvfrom(udpSocket, buf, MAXBYTE, 0, (SOCKADDR*)&otherAddr, &addrLen);
const int szAddrlen = 17;
char szOtherAddr[szAddrlen];
inet_ntop(PF_INET, (LPVOID)&otherAddr, szOtherAddr, szAddrlen);
printf("receive from %s:%d, buffer = %s", szOtherAddr, otherAddr.sin_port, buf);
char *sendMsg = "hello world";
sendto(udpSocket, sendMsg, strlen(sendMsg) + sizeof(char), 0, (SOCKADDR*)&otherAddr, addrLen);
closesocket(udpSocket);
WSACleanup();
return 0;
}
C/C++ Windows API——Udp
最新推荐文章于 2024-05-17 03:15:52 发布