#include "stdafx.h"
#include
#include
#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) {
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
#define SOCK_DGRAM 2
#define SOCK_RAW 3
#define SOCK_RDM 4
#define SOCK_SEQPACKET 5
typedef enum {
#if(_WIN32_WINNT >= 0x0501)
IPPROTO_HOPOPTS = 0,
#endif
IPPROTO_ICMP = 1,
IPPROTO_IGMP = 2,
IPPROTO_GGP = 3,
#if(_WIN32_WINNT >= 0x0501)
IPPROTO_IPV4 = 4,
#endif
#if(_WIN32_WINNT >= 0x0600)
IPPROTO_ST = 5,
#endif
IPPROTO_TCP = 6,
#if(_WIN32_WINNT >= 0x0600)
IPPROTO_CBT = 7,
IPPROTO_EGP = 8,
IPPROTO_IGP = 9,
#endif
IPPROTO_PUP = 12,
IPPROTO_UDP = 17,
IPPROTO_IDP = 22,
#if(_WIN32_WINNT >= 0x0600)
IPPROTO_RDP = 27,
#endif
#if(_WIN32_WINNT >= 0x0501)
IPPROTO_IPV6 = 41,
IPPROTO_ROUTING = 43,
IPPROTO_FRAGMENT = 44,
IPPROTO_ESP = 50,
IPPROTO_AH = 51,
IPPROTO_ICMPV6 = 58,
IPPROTO_NONE = 59,
IPPROTO_DSTOPTS = 60,
#endif
IPPROTO_ND = 77,
#if(_WIN32_WINNT >= 0x0501)
IPPROTO_ICLFXBM = 78,
#endif
#if(_WIN32_WINNT >= 0x0600)
IPPROTO_PIM = 103,
IPPROTO_PGM = 113,
IPPROTO_L2TP = 115,
IPPROTO_SCTP = 132,
#endif
IPPROTO_RAW = 255,
IPPROTO_MAX = 256,
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);
/*
typedef struct sockaddr {
#if (_WIN32_WINNT < 0x0600)
u_short sa_family;
#else
ADDRESS_FAMILY sa_family;
#endif
CHAR sa_data[14];
} SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;
typedef struct sockaddr_in {
#if(_WIN32_WINNT < 0x0600)
short sin_family;
#else
ADDRESS_FAMILY sin_family;
#endif
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;
}