基於無連接的Udp編程.
代碼註釋,如下:
- //Server.cpp
- #include <stdio.h>
- #include <winsock2.h>
- #pragma comment(lib,"WS2_32.lib")
- #define BUF_SIZE 64
- int main()
- {
- WSADATA wsadata; //包含DLL期望程序使用的版本和支持的最高版本等字段
- int retVal;
- SOCKET sServer;
- char buf[BUF_SIZE];
- //加載套接字DLL
- retVal=WSAStartup(MAKEWORD(2,2),&wsadata);
- if(retVal != 0)
- {
- printf("WSAStartup failed!\n");
- }
- //創建套接字
- sServer=socket(AF_INET,SOCK_DGRAM,IPPROTO_IP);
- if(sServer == INVALID_SOCKET)
- {
- printf("socket failed!\n");
- WSACleanup();
- return -1;
- }
- //綁定套接字(綁定套接字時,需要明確指出服務器的各個地址字段)
- SOCKADDR_IN addrServ;
- addrServ.sin_family=AF_INET; //套接字屬於協議族TCP/IP
- addrServ.sin_port=htons(4999);
- addrServ.sin_addr.S_un.S_addr=INADDR_ANY;
- retVal=bind(sServer,(LPSOCKADDR)&addrServ,sizeof(SOCKADDR_IN));
- if(retVal == SOCKET_ERROR)
- {
- printf("bind failed!\n");
- closesocket(sServer);
- WSACleanup();
- return -1;
- }
- //接收數據
- SOCKADDR_IN addrClient; //接收數據時,系統自動填充地址字段
- int len=sizeof(SOCKADDR_IN);
- ZeroMemory(buf,BUF_SIZE);
- retVal=recvfrom(sServer,buf,BUF_SIZE,0,(LPSOCKADDR)&addrClient,&len);
- if(retVal == SOCKET_ERROR)
- {
- printf("recvfrom failed!\n");
- closesocket(sServer);
- WSACleanup();
- return -1;
- }
- //
- printf("Server receives data: ");
- printf("%s\n",buf);
- //
- closesocket(sServer);
- WSACleanup();
- return 0;
- }
- //Client.cpp
- #include <stdio.h>
- #include <winsock2.h>
- #pragma comment(lib,"WS2_32.lib")
- #define BUF_SIZE 64
- int main()
- {
- WSADATA wsadata;
- int retVal;
- SOCKET sClient;
- char buf[BUF_SIZE];
- //加載套接字DLL
- retVal=WSAStartup(MAKEWORD(2,2),&wsadata);
- if(retVal != 0)
- {
- printf("WSAStartup failed!\n");
- }
- //創建套接字
- sClient=socket(AF_INET,SOCK_DGRAM,IPPROTO_IP);
- if(sClient == INVALID_SOCKET)
- {
- printf("socket failed!\n");
- WSACleanup();
- return -1;
- }
- //發送數據(發送數據時,需要明確指出服務器的各個地址字段)
- SOCKADDR_IN addrServ;
- addrServ.sin_family=AF_INET; //套接字屬於協議族TCP/IP
- addrServ.sin_port=htons(4999);
- addrServ.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
- ZeroMemory(buf,BUF_SIZE);
- strcpy(buf,"Hello Udp!");
- retVal=sendto(sClient,buf,BUF_SIZE,0,(LPSOCKADDR)&addrServ,sizeof(SOCKADDR_IN));
- if(retVal == SOCKET_ERROR)
- {
- printf("sendto failed!\n");
- closesocket(sClient);
- WSACleanup();
- return -1;
- }
- //
- closesocket(sClient);
- WSACleanup();
- return 0;
- }
*************************************************************************
補充說明:
1.
#define INVALID_SOCKET (SOCKET)(~0)
#define SOCKET_ERROR (-1)
#define INADDR_ANY (u_long)0x00000000
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"WS2_32.lib") //#pragma comment(Comment-Type,"CommentString")
①頭文件,只有函數的聲明;(編譯階段連接進去)②庫文件,如果有DLL,則充當索引的作用;如果沒有,則包含函數的實現代碼;(鏈接階段)③DLL,在運行階段,把函數的實現代碼連接進去.
2.
typedef struct WSAData {
WORD wVersion; //系統希望程序使用的庫版本
WORD wHighVersion; //系統支持的最高版本
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR* lpVendorInfo; } WSADATA,
*LPWSADATA;
3.
int WSAStartup( WORD wVersionRequested, LPWSADATA lpWSAData );Return Values
The WSAStartup function returns zero if successful. Otherwise, it returns one of the error codes listed in the following.(WSASYSNOREADY | WSAEFAULT)
4.
對於main()函數而言,返0,則表示成功執行;返其它,則表示程序執行異常.
*************************************************************************
函數原型:
1.
int sendto( SOCKET s, const char* buf, int len, int flags, const struct sockaddr* to, int tolen );
int flags, //MSG_OOB | MSG_DONTROUTE
int flags, //MSG_OOB | MSG_PEEK
int recvfrom( SOCKET s, char FAR* buf, int len, int flags, struct sockaddr FAR* from, int FAR* fromlen );