您好,登錄后才能下訂單哦!
本文實(shí)例為大家分享了C語(yǔ)言UDP傳輸系統(tǒng)的具體代碼,供大家參考,具體內(nèi)容如下
/*加載庫(kù)文件*/ #pragma comment( lib, "ws2_32.lib" ) /*加載頭文件*/ #include <winsock2.h> #include <ws2tcpip.h> #include <stdio.h> #include <stdlib.h> /*定義多播常量*/ #define MCASTADDR "224.3.5.8" #define MCASTPORT 25000 #define BUFSIZE 1024 #define MCOUNT 10 /*定義廣播常量*/ #define BCASTPORT 5050 #define BCOUNT 10 /*定義廣播全局變量*/ SOCKET socketBro; SOCKET socketRec; struct sockaddr_in addrBro; struct sockaddr_in addrRec; BOOL broadSendFlag; BOOL broadFlag; DWORD bCount; DWORD bcastAddr; short bPort; /*定義多播全局變量*/ SOCKET socketMul; SOCKET sockJoin; struct sockaddr_in addrLocal; struct sockaddr_in addrMul; BOOL multiSendFlag; BOOL bLoopBack; BOOL multiFlag; DWORD dwInterface; DWORD dwMulticastGroup; DWORD mCount; short mPort; /*自定義函數(shù)*/ void initial(); void GetArgments(int argc, char **argv); void userHelpAll(); void userHelpBro(); void userHelpMul(); void broadcastSend(); void broadcastRec(); void mulControl(); void multicastSend(); void multicastRec(); /*初始化全局變量函數(shù)*/ void initial() { /*初始化廣播全局變量*/ bPort = BCASTPORT; bCount = BCOUNT; bcastAddr = INADDR_BROADCAST; broadSendFlag = FALSE; broadFlag = FALSE; multiFlag = FALSE; /*初始化多播全局變量*/ dwInterface = INADDR_ANY; dwMulticastGroup = inet_addr(MCASTADDR); mPort = MCASTPORT; mCount = MCOUNT; multiSendFlag = FALSE; bLoopBack = FALSE; } /*參數(shù)獲取函數(shù)*/ void GetArgments(int argc, char **argv) { int i; /*如果參數(shù)個(gè)數(shù)小于2個(gè)*/ if(argc<=1) { userHelpAll(); return ; } /*獲取廣播選項(xiàng)*/ if(argv[1][0]=='-'&&argv[1][1]=='b') { /*廣播標(biāo)志設(shè)置為真*/ broadFlag = TRUE; for(i=2; i < argc ;i++) { if (argv[i][0] == '-') { switch (tolower(argv[i][1])) { /*如果是發(fā)送者*/ case 's': broadSendFlag = TRUE; break; /*廣播的地址*/ case 'h': if (strlen(argv[i]) > 3) bcastAddr = inet_addr(&argv[i][3]); break; /*廣播的端口號(hào)*/ case 'p': if (strlen(argv[i]) > 3) bPort = atoi(&argv[i][3]); break; /*廣播(接收或者發(fā)送)的數(shù)量*/ case 'n': bCount = atoi(&argv[i][3]); break; /*其他情況顯示用戶(hù)幫助,終止程序*/ default: { userHelpBro(); ExitProcess(-1); } break; } } } return ; } /*獲取多播選項(xiàng)*/ if(argv[1][0]=='-'&&argv[1][1]=='m') { /*多播標(biāo)志設(shè)置為真*/ multiFlag = TRUE; for(i=2; i < argc ;i++) { if (argv[i][0] == '-') { switch (tolower(argv[i][1])) { /*如果是發(fā)送者*/ case 's': multiSendFlag = TRUE; break; /*多播地址*/ case 'h': if (strlen(argv[i]) > 3) dwMulticastGroup = inet_addr(&argv[i][3]); break; /*本地接口地址*/ case 'i': if (strlen(argv[i]) > 3) dwInterface = inet_addr(&argv[i][3]); break; /*多播端口號(hào)*/ case 'p': if (strlen(argv[i]) > 3) mPort = atoi(&argv[i][3]); break; /*環(huán)回標(biāo)志設(shè)置為真*/ case 'l': bLoopBack = TRUE; break; /*發(fā)送(接收)的數(shù)量*/ case 'n': mCount = atoi(&argv[i][3]); break; /*其他情況,顯示用戶(hù)幫助,終止程序*/ default: userHelpMul(); break; } } } } return; } /*全局用戶(hù)幫助函數(shù)*/ void userHelpAll() { printf("Please choose broadcast[-b] or multicast[-m] !\n"); printf("userHelpAll: -b [-s][p][-h][-n] | -m[-s][-h][-p][-i][-l][-n]\n"); userHelpBro(); userHelpMul(); } /*廣播用戶(hù)幫助函數(shù)*/ void userHelpBro() { printf("Broadcast: -b -s:str -p:int -h:str -n:int\n"); printf(" -b Start the broadcast program.\n"); printf(" -s Act as server (send data); otherwise\n"); printf(" receive data. Default is receiver.\n"); printf(" -p:int Port number to use\n "); printf(" The default port is 5050.\n"); printf(" -h:str The decimal broadcast IP address.\n"); printf(" -n:int The Number of messages to send/receive.\n"); printf(" The default number is 10.\n"); } /*多播用戶(hù)幫助函數(shù)*/ void userHelpMul() { printf("Multicast: -m -s -h:str -p:int -i:str -l -n:int\n"); printf(" -m Start the multicast program.\n"); printf(" -s Act as server (send data); otherwise\n"); printf(" receive data. Default is receiver.\n"); printf(" -h:str The decimal multicast IP address to join\n"); printf(" The default group is: %s\n", MCASTADDR); printf(" -p:int Port number to use\n"); printf(" The default port is: %d\n", MCASTPORT); printf(" -i:str Local interface to bind to; by default \n"); printf(" use INADDRY_ANY\n"); printf(" -l Disable loopback\n"); printf(" -n:int Number of messages to send/receive\n"); ExitProcess(-1); } /*廣播消息發(fā)送函數(shù)*/ void broadcastSend() { /*設(shè)置廣播的消息*/ char *smsg="The message received is from sender!"; BOOL opt=TRUE; int nlen=sizeof(addrBro); int ret; DWORD i=0; /*創(chuàng)建UDP套接字*/ socketBro=WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_OVERLAPPED); /*如果創(chuàng)建失敗*/ if(socketBro==INVALID_SOCKET) { printf("Create socket failed:%d\n",WSAGetLastError()); WSACleanup(); return; } /*設(shè)置廣播地址各個(gè)選項(xiàng)*/ addrBro.sin_family=AF_INET; addrBro.sin_addr.s_addr=bcastAddr; addrBro.sin_port=htons(bPort); /*設(shè)置該套接字為廣播類(lèi)型*/ if (setsockopt(socketBro,SOL_SOCKET,SO_BROADCAST,(char FAR *)&opt, sizeof(opt))==SOCKET_ERROR) /*如果設(shè)置失敗*/ { printf("setsockopt failed:%d",WSAGetLastError()); closesocket(socketBro); WSACleanup(); return; } /*循環(huán)發(fā)送消息*/ while(i<bCount) { /*延遲1秒*/ Sleep(1000); /*從廣播地址發(fā)送消息*/ ret=sendto(socketBro,smsg,256,0,(struct sockaddr*)&addrBro,nlen); /*如果發(fā)送失敗*/ if(ret==SOCKET_ERROR) printf("Send failed:%d",WSAGetLastError()); /*如果發(fā)送成功*/ else { printf("Send message %d!\n",i); } i++; } /*發(fā)送完畢后關(guān)閉套接字、釋放占用資源*/ closesocket(socketBro); WSACleanup(); } /*廣播消息接收函數(shù)*/ void broadcastRec() { BOOL optval = TRUE; int addrBroLen; char buf[256]; DWORD i=0; /*該地址用來(lái)綁定套接字*/ addrRec.sin_family=AF_INET; addrRec.sin_addr.s_addr=0; addrRec.sin_port=htons(bPort); /*該地址用來(lái)接收網(wǎng)路上廣播的消息*/ addrBro.sin_family=AF_INET; addrBro.sin_addr.s_addr=bcastAddr; addrBro.sin_port=htons(bPort); addrBroLen=sizeof(addrBro); //創(chuàng)建UDP套接字 socketRec=socket(AF_INET,SOCK_DGRAM,0); /*如果創(chuàng)建失敗*/ if(socketRec==INVALID_SOCKET) { printf("Create socket error:%d",WSAGetLastError()); WSACleanup(); return; } /*設(shè)置該套接字為可重用類(lèi)型*/ if(setsockopt(socketRec,SOL_SOCKET,SO_REUSEADDR,(char FAR *)&optval, sizeof(optval))==SOCKET_ERROR) /*如果設(shè)置失敗*/ { printf("setsockopt failed:%d",WSAGetLastError()); closesocket(socketRec); WSACleanup(); return; } /*綁定套接字和地址*/ if(bind(socketRec,(struct sockaddr *)&addrRec, sizeof(struct sockaddr_in))==SOCKET_ERROR) /*如果綁定失敗*/ { printf("bind failed with: %d\n", WSAGetLastError()); closesocket(socketRec); WSACleanup(); return ; } /*從廣播地址接收消息*/ while(i<bCount) { recvfrom(socketRec,buf,256,0,(struct sockaddr FAR *)&addrBro,(int FAR *)&addrBroLen); /*延遲2秒鐘*/ Sleep(2000); /*輸出接收到緩沖區(qū)的消息*/ printf("%s\n",buf); /*情況緩沖區(qū)*/ ZeroMemory(buf,256); i++; } /*接收完畢后關(guān)閉套接字、釋放占用資源*/ closesocket(socketRec); WSACleanup(); } /*多播控制函數(shù)*/ void mulControl() { int optval; /*創(chuàng)建UDP套接字,用于多播*/ if ((socketMul = WSASocket(AF_INET, SOCK_DGRAM, 0, NULL, 0, WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF | WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET) { printf("socket failed with: %d\n", WSAGetLastError()); WSACleanup(); return ; } /*設(shè)置本地接口地址*/ addrLocal.sin_family = AF_INET; addrLocal.sin_port = htons(mPort); addrLocal.sin_addr.s_addr = dwInterface; /*將UDP套接字綁定到本地地址上*/ if (bind(socketMul, (struct sockaddr *)&addrLocal, sizeof(addrLocal)) == SOCKET_ERROR) /*如果綁定失敗*/ { printf("bind failed with: %d\n", WSAGetLastError()); closesocket(socketMul); WSACleanup(); return ; } /*設(shè)置多播地址各個(gè)選項(xiàng)*/ addrMul.sin_family = AF_INET; addrMul.sin_port = htons(mPort); addrMul.sin_addr.s_addr = dwMulticastGroup; /*重新設(shè)置TTL值*/ optval = 8; /*設(shè)置多播數(shù)據(jù)的TTL(存在時(shí)間)值。默認(rèn)情況下,TTL值是1*/ if (setsockopt(socketMul, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&optval, sizeof(int)) == SOCKET_ERROR) /*如果設(shè)置失敗*/ { printf("setsockopt(IP_MULTICAST_TTL) failed: %d\n",WSAGetLastError()); closesocket(socketMul); WSACleanup(); return ; } /*如果指定了返還選項(xiàng)*/ if (bLoopBack) { /*設(shè)置返還選項(xiàng)為假,禁止將發(fā)送的數(shù)據(jù)返還給本地接口*/ optval = 0; if (setsockopt(socketMul, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&optval, sizeof(optval)) == SOCKET_ERROR) /*如果設(shè)置失敗*/ { printf("setsockopt(IP_MULTICAST_LOOP) failed: %d\n", WSAGetLastError()); closesocket(socketMul); WSACleanup(); return ; } } /*加入多播組*/ if ((sockJoin = WSAJoinLeaf(socketMul, (SOCKADDR *)&addrMul, sizeof(addrMul), NULL, NULL, NULL, NULL, JL_BOTH)) == INVALID_SOCKET) /*如果加入不成功*/ { printf("WSAJoinLeaf() failed: %d\n", WSAGetLastError()); closesocket(socketMul); WSACleanup(); return ; } } /*多播消息發(fā)送函數(shù)*/ void multicastSend() { TCHAR sendbuf[BUFSIZE]; DWORD i; int ret; mulControl(); /*發(fā)送mCount條消息*/ for(i = 0; i < mCount; i++) { /*將待發(fā)送的消息寫(xiě)入發(fā)送緩沖區(qū)*/ sprintf(sendbuf, "server 1: This is a test: %d", i); ret=sendto(socketMul, (char *)sendbuf, strlen(sendbuf), 0, (struct sockaddr *)&addrMul, sizeof(addrMul)); /*如果發(fā)送失敗*/ if(ret==SOCKET_ERROR) { printf("sendto failed with: %d\n",WSAGetLastError()); closesocket(sockJoin); closesocket(socketMul); WSACleanup(); return ; } /*如果發(fā)送成功*/ else printf("Send message %d\n",i); Sleep(500); } /*關(guān)閉套接字、釋放占用資源*/ closesocket(socketMul); WSACleanup(); } /*多播消息接收函數(shù)*/ void multicastRec() { DWORD i; struct sockaddr_in from; TCHAR recvbuf[BUFSIZE]; int ret; int len = sizeof(struct sockaddr_in); mulControl(); /*接收mCount條消息*/ for(i = 0; i < mCount; i++) { /*將接收的消息寫(xiě)入接收緩沖區(qū)*/ if ((ret = recvfrom(socketMul, recvbuf, BUFSIZE, 0, (struct sockaddr *)&from, &len)) == SOCKET_ERROR) /*如果接收不成功*/ { printf("recvfrom failed with: %d\n",WSAGetLastError()); closesocket(sockJoin); closesocket(socketMul); WSACleanup(); return ; } /*接收成功,輸出接收的消息*/ recvbuf[ret] = 0; printf("RECV: '%s' from <%s>\n", recvbuf,inet_ntoa(from.sin_addr)); } /*關(guān)閉套接字、釋放占用資源*/ closesocket(socketMul); WSACleanup(); } /*主函數(shù)*/ int main(int argc, char **argv) { WSADATA wsd; initial(); GetArgments(argc, argv); /*初始化Winsock*/ if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0) { printf("WSAStartup() failed\n"); return -1; } /*如果是執(zhí)行廣播程序*/ if(broadFlag) { /*以發(fā)送者身份發(fā)送消息*/ if(broadSendFlag) { broadcastSend(); return 0; } /*以接收者身份接收消息*/ else { broadcastRec(); return 0; } } /*如果是執(zhí)行多播程序*/ if(multiFlag) { /*以發(fā)送者身份發(fā)送消息*/ if(multiSendFlag) { multicastSend(); return 0; } /*以接收者身份接收消息*/ else { multicastRec(); return 0; } } return 0; }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。