C語言UDP傳輸系統(tǒng)源碼
更新時間:2018年02月28日 08:57:49 投稿:lijiao
這篇文章主要為大家分享了C語言UDP傳輸系統(tǒng)的源碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了C語言UDP傳輸系統(tǒng)的具體代碼,供大家參考,具體內(nèi)容如下
/*加載庫文件*/
#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ù)個數(shù)小于2個*/
if(argc<=1)
{
userHelpAll();
return ;
}
/*獲取廣播選項*/
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;
/*廣播的端口號*/
case 'p':
if (strlen(argv[i]) > 3)
bPort = atoi(&argv[i][3]);
break;
/*廣播(接收或者發(fā)送)的數(shù)量*/
case 'n':
bCount = atoi(&argv[i][3]);
break;
/*其他情況顯示用戶幫助,終止程序*/
default:
{
userHelpBro();
ExitProcess(-1);
}
break;
}
}
}
return ;
}
/*獲取多播選項*/
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;
/*多播端口號*/
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;
/*其他情況,顯示用戶幫助,終止程序*/
default:
userHelpMul();
break;
}
}
}
}
return;
}
/*全局用戶幫助函數(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();
}
/*廣播用戶幫助函數(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");
}
/*多播用戶幫助函數(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è)置廣播地址各個選項*/
addrBro.sin_family=AF_INET;
addrBro.sin_addr.s_addr=bcastAddr;
addrBro.sin_port=htons(bPort);
/*設(shè)置該套接字為廣播類型*/
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;
/*該地址用來綁定套接字*/
addrRec.sin_family=AF_INET;
addrRec.sin_addr.s_addr=0;
addrRec.sin_port=htons(bPort);
/*該地址用來接收網(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è)置該套接字為可重用類型*/
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è)置多播地址各個選項*/
addrMul.sin_family = AF_INET;
addrMul.sin_port = htons(mPort);
addrMul.sin_addr.s_addr = dwMulticastGroup;
/*重新設(shè)置TTL值*/
optval = 8;
/*設(shè)置多播數(shù)據(jù)的TTL(存在時間)值。默認(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 ;
}
/*如果指定了返還選項*/
if (bLoopBack)
{
/*設(shè)置返還選項為假,禁止將發(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ā)送的消息寫入發(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++)
{
/*將接收的消息寫入接收緩沖區(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;
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:
相關(guān)文章
Win10下最新版CLion(2020.1.3)安裝及環(huán)境配置教程詳解
這篇文章主要介紹了Win10下最新版CLion(2020.1.3)安裝及環(huán)境配置,CLion 是 JetBrains 推出的全新的 C/C++ 跨平臺集成開發(fā)環(huán)境,本文給大家介紹的非常詳細(xì),需要的朋友可以參考下2020-08-08
C語言超詳細(xì)講解函數(shù)棧幀的創(chuàng)建和銷毀
我們知道c語言中函數(shù)都是被調(diào)用的,main函數(shù)里面能調(diào)用其他函數(shù),其實main函數(shù)也是被別的函數(shù)調(diào)用的,下面通過本文給大家分享c語言函數(shù)棧幀的創(chuàng)建和銷毀過程,一起看看吧2022-05-05
C/C++關(guān)于實現(xiàn)CAN信號的獲取方法
這篇文章主要介紹了C/C++關(guān)于實現(xiàn)CAN信號的獲取方法,標(biāo)準(zhǔn)的CAN 數(shù)據(jù)為8字節(jié),即64位,但是CAN FD的最大數(shù)據(jù)可為64字節(jié),為512位,其中的幀ID分為標(biāo)準(zhǔn)幀和擴展幀,其中用11位標(biāo)準(zhǔn)幀,用29位表示擴展幀2023-02-02
Qt5.9實現(xiàn)簡單的多線程實例(類QThread)
Qt開啟多線程,主要用到類QThread。用一個類繼承QThread,然后重新改寫虛函數(shù)run()。具有一定的參考價值,感興趣的可以了解一下2021-09-09
C++在C語言基礎(chǔ)之上增強的幾個實用特性總結(jié)
這篇文章主要介紹了C++在C語言基礎(chǔ)之上增強的幾個實用特性總結(jié),包括C++中更強的類型約束以及結(jié)構(gòu)體方面等一些更加高級的特性,需要的朋友可以參考下2016-03-03
使用C++17實現(xiàn)JSON庫設(shè)計思路示例全解
這篇文章主要為大家介紹了使用C++17實現(xiàn)JSON庫設(shè)計思路示例全解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08

