在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于UDP的C/S模型代碼實現

科技綠洲 ? 來源:Linux開發架構之路 ? 作者:Linux開發架構之路 ? 2023-11-10 10:41 ? 次閱讀

UDP服務器

傳輸層主要應用的協議模型有兩種,一種是TCP協議,另外一種則是UDP協議。TCP協議在網絡通信中占主導地位,絕大多數的網絡通信借助TCP協議完成數據傳輸。但UDP也是網絡通信中不可或缺的重要通信手段。

相較于TCP而言,UDP通信的形式更像是發短信。不需要在數據傳輸之前建立、維護連接。只專心獲取數據就好。省去了三次握手的過程,通信速度可以大大提高,但與之伴隨的通信的穩定性和正確率便得不到保證。因此,我們稱UDP為“無連接的不可靠報文傳遞”。

那么與我們熟知的TCP相比,UDP有哪些優點和不足呢?由于無需創建連接,所以UDP開銷較小,數據傳輸速度快,實時性較強。多用于對實時性要求較高的通信場合,如視頻會議、電話會議等。但隨之也伴隨著數據傳輸不可靠,傳輸數據的正確率、傳輸順序和流量都得不到控制和保證。所以,通常情況下,使用UDP協議進行數據傳輸,為保證數據的正確性,我們需要在應用層添加輔助校驗協議來彌補UDP的不足,以達到數據可靠傳輸的目的。

與TCP類似的,UDP也有可能出現緩沖區被填滿后,再接收數據時丟包的現象。由于它沒有TCP滑動窗口的機制,通常采用如下兩種方法解決:

1)服務器應用層設計流量控制,控制發送數據速度。

2)借助setsockopt函數改變接收緩沖區大小。如:

#include < sys/socket.h >
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
	int n = 220x1024
	setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n));

C/S模型

圖片

由于UDP不需要維護連接,程序邏輯簡單了很多,但是UDP協議是不可靠的,保證通訊可靠性的機制需要在應用層實現。

編譯運行server,在兩個終端里各開一個client與server交互,看看server是否具有并發服務的能力。用Ctrl+C關閉server,然后再運行server,看此時client還能否和server聯系上。和TCP程序的運行結果相比較,體會無連接的含義。

server

#include < string.h >
#include < netinet/in.h >
#include < stdio.h >
#include < unistd.h >
#include < strings.h >
#include < arpa/inet.h >
#include < ctype.h >

#define MAXLINE 80
#define SERV_PORT 6666

int main(void)
{
	struct sockaddr_in servaddr, cliaddr;
	socklen_t cliaddr_len;
	int sockfd;
	char buf[MAXLINE];
	char str[INET_ADDRSTRLEN];
	int i, n;

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(SERV_PORT);

	bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
	printf("Accepting connections ...n");

	while (1) {
		cliaddr_len = sizeof(cliaddr);
		n = recvfrom(sockfd, buf, MAXLINE,0, (struct sockaddr *)&cliaddr, &cliaddr_len);
		if (n == -1)
			perror("recvfrom error");
		printf("received from %s at PORT %dn", 
				inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
				ntohs(cliaddr.sin_port));
		for (i = 0; i < n; i++)
			buf[i] = toupper(buf[i]);

		n = sendto(sockfd, buf, n, 0, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
		if (n == -1)
			perror("sendto error");
	}
	close(sockfd);
	return 0;
}

client

#include < stdio.h >
#include < string.h >
#include < unistd.h >
#include < netinet/in.h >
#include < arpa/inet.h >
#include < strings.h >
#include < ctype.h >

#define MAXLINE 80
#define SERV_PORT 6666

int main(int argc, char *argv[])
{
	struct sockaddr_in servaddr;
	int sockfd, n;
	char buf[MAXLINE];

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);

	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
	servaddr.sin_port = htons(SERV_PORT);

	while (fgets(buf, MAXLINE, stdin) != NULL) {
		n = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
		if (n == -1)
			perror("sendto error");
		n = recvfrom(sockfd, buf, MAXLINE, 0, NULL, 0);
		if (n == -1)
			perror("recvfrom error");
		write(STDOUT_FILENO, buf, n);
	}
	close(sockfd);
	return 0;
}

多播(組播)

組播組可以是永久的也可以是臨時的。組播組地址中,有一部分由官方分配的,稱為永久組播組。永久組播組保持不變的是它的ip地址,組中的成員構成可以發生變化。永久組播組中成員的數量都可以是任意的,甚至可以為零。那些沒有保留下來供永久組播組使用的ip組播地址,可以被臨時組播組利用。

224.0.0.0~224.0.0.255 為預留的組播地址(永久組地址),地址224.0.0.0保留不做分配,其它地址供路由協議使用;
224.0.1.0~224.0.1.255 是公用組播地址,可以用于Internet;欲使用需申請。
224.0.2.0~238.255.255.255 為用戶可用的組播地址(臨時組地址),全網范圍內有效;
239.0.0.0~239.255.255.255 為本地管理組播地址,僅在特定的本地范圍內有效。

可使用ip ad命令查看網卡編號,如:

itcast$ ip ad
1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
link/ether 00:0c:29:0a:c4:f4 brd ff:ff:ff:ff:ff:ff
inet6 fe80::20c:29ff:fe0a:c4f4/64 scope link
valid_lft forever preferred_lft forever

if_nametoindex 命令可以根據網卡名,獲取網卡序號。

server

#include < stdio.h >
#include < stdlib.h >
#include < sys/types.h >
#include < sys/socket.h >
#include < string.h >
#include < unistd.h >
#include < arpa/inet.h >
#include < net/if.h >

#define SERVER_PORT 6666
#define CLIENT_PORT 9000
#define MAXLINE 1500
#define GROUP "239.0.0.2"

int main(void)
{
	int sockfd, i ;
	struct sockaddr_in serveraddr, clientaddr;
	char buf[MAXLINE] = "itcastn";
	char ipstr[INET_ADDRSTRLEN]; /* 16 Bytes */
	socklen_t clientlen;
	ssize_t len;
	struct ip_mreqn group;

	/* 構造用于UDP通信的套接字 */
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);

	bzero(&serveraddr, sizeof(serveraddr));
	serveraddr.sin_family = AF_INET; /* IPv4 */
	serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); /* 本地任意IP INADDR_ANY = 0 */
	serveraddr.sin_port = htons(SERVER_PORT);

	bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));

	/*設置組地址*/
	inet_pton(AF_INET, GROUP, &group.imr_multiaddr);
	/*本地任意IP*/
	inet_pton(AF_INET, "0.0.0.0", &group.imr_address);
	/* eth0 -- > 編號 命令:ip ad */
	group.imr_ifindex = if_nametoindex("eth0");
	setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF, &group, sizeof(group));

	/*構造 client 地址 IP+端口 */
	bzero(&clientaddr, sizeof(clientaddr));
	clientaddr.sin_family = AF_INET; /* IPv4 */
	inet_pton(AF_INET, GROUP, &clientaddr.sin_addr.s_addr);
	clientaddr.sin_port = htons(CLIENT_PORT);

	while (1) {
		//fgets(buf, sizeof(buf), stdin);
		sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&clientaddr, sizeof(clientaddr));
		sleep(1);
	}
	close(sockfd);
	return 0;
}

client

#include < netinet/in.h >
#include < stdio.h >
#include < sys/types.h >
#include < sys/socket.h >
#include < arpa/inet.h >
#include < string.h >
#include < stdlib.h >
#include < sys/stat.h >
#include < unistd.h >
#include < fcntl.h >
#include < net/if.h >

#define SERVER_PORT 6666
#define MAXLINE 4096
#define CLIENT_PORT 9000
#define GROUP "239.0.0.2"

int main(int argc, char *argv[])
{
	struct sockaddr_in serveraddr, localaddr;
	int confd;
	ssize_t len;
	char buf[MAXLINE];

	/* 定義組播結構體 */
	struct ip_mreqn group;
	confd = socket(AF_INET, SOCK_DGRAM, 0);

	//初始化本地端地址
	bzero(&localaddr, sizeof(localaddr));
	localaddr.sin_family = AF_INET;
	inet_pton(AF_INET, "0.0.0.0" , &localaddr.sin_addr.s_addr);
	localaddr.sin_port = htons(CLIENT_PORT);

	bind(confd, (struct sockaddr *)&localaddr, sizeof(localaddr));

	/*設置組地址*/
	inet_pton(AF_INET, GROUP, &group.imr_multiaddr);
	/*本地任意IP*/
	inet_pton(AF_INET, "0.0.0.0", &group.imr_address);
	/* eth0 -- > 編號 命令:ip ad */
	group.imr_ifindex = if_nametoindex("eth0");
	/*設置client 加入多播組 */
	setsockopt(confd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &group, sizeof(group));

	while (1) {
		len = recvfrom(confd, buf, sizeof(buf), 0, NULL, 0);
		write(STDOUT_FILENO, buf, len);
	}
	close(confd);
	return 0;
}
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 數據傳輸
    +關注

    關注

    9

    文章

    2005

    瀏覽量

    65729
  • UDP
    UDP
    +關注

    關注

    0

    文章

    330

    瀏覽量

    34484
  • 模型
    +關注

    關注

    1

    文章

    3493

    瀏覽量

    50024
  • 代碼
    +關注

    關注

    30

    文章

    4889

    瀏覽量

    70281
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    實現TCP的C代碼封裝(含代碼

    實現TCP的C代碼封裝(含代碼
    的頭像 發表于 09-28 16:03 ?2930次閱讀
    <b class='flag-5'>實現</b>TCP的<b class='flag-5'>C</b><b class='flag-5'>代碼</b>封裝(含<b class='flag-5'>代碼</b>)

    S7-1200與S7-1200/S7-1500不同項目下UDP通信

    S7-1200 與 S7-1200 之間的以太網通信可以通過 UDP 協議來實現。本列中使用TSEND_C,TRCV_
    的頭像 發表于 01-10 09:19 ?7143次閱讀

    UDP穿透NAT的原理與實現(附源代碼

    UDP穿透NAT的原理與實現(附源代碼)論壇上經常有對P2P原理的討論
    發表于 02-09 14:36 ?30次下載

    基于UDP協議的Socket網絡編程模式的實現

    傳輸層進行網絡通信編程的接口是Socket&它是通用的開發網絡通信程序標準) 本文介紹了基于UDP協議Socket編程機制和原理& 提出了在C/ S模型下以Java Socket來部署
    發表于 09-09 15:10 ?42次下載

    UDP協議,UDP協議是什么意思

    UDP協議,UDP協議是什么意思 UDP 是User Datagram Protocol的簡稱, 中文名是用戶數據包協議,是 OSI 參考模型中一種無連接的傳輸層協議,
    發表于 03-29 17:35 ?1542次閱讀

    實例64 UDP服務器模型

    JAVA教程之UDP服務器模型,很好的JAVA的資料,快來學習吧
    發表于 04-11 17:28 ?2次下載

    JAVA教程之UDP客戶端模型

    JAVA教程之UDP客戶端模型,很好的JAVA的資料,快來學習吧
    發表于 04-11 17:28 ?4次下載

    基于ARM9的UDP協議棧的設計與實現

    基于ARM9的UDP協議棧的設計與實現
    發表于 01-19 21:22 ?9次下載

    UDP協議的設計與實現資料總結

    本文檔的主要內容詳細介紹的是UDP協議的設計與實現資料總結
    發表于 11-06 18:03 ?16次下載
    <b class='flag-5'>UDP</b>協議的設計與<b class='flag-5'>實現</b>資料總結

    UDP及TCP通信的程序設計和源代碼免費下載

    本文檔的主要內容詳細介紹的是UDP及TCP通信的程序設計和源代碼免費下載。
    發表于 01-08 15:12 ?37次下載
    <b class='flag-5'>UDP</b>及TCP通信的程序設計和源<b class='flag-5'>代碼</b>免費下載

    如何利用Java代碼實現UDP和TCP通信

    UDP是一種面向無連接的協議,因此傳輸過程中不能保證數據的完整性。jdk提供了網絡通信包,在java.net包下提供了兩個類DatagramPacket和DatagramSocket來實現UDP通信
    發表于 08-04 10:03 ?2833次閱讀
    如何利用Java<b class='flag-5'>代碼</b><b class='flag-5'>實現</b><b class='flag-5'>UDP</b>和TCP通信

    S7-1200與S7-300 PN/S7-400 PN UDP STEP7通信

    S7-1200 與 S7-300 PN 口之間的以太網通信可以通過 UDP 協議來實現,使用的通信指令是在雙方 CPU 調用通信-開放式用戶通信TSEND_
    的頭像 發表于 04-11 10:15 ?5056次閱讀

    UDP和調試助手介紹

    S7-1200支持UDP單播和UDP廣播,不支持UDP組播。UDP是一種無連接的通信協議,通過調用TSEND_
    的頭像 發表于 03-20 11:22 ?9726次閱讀

    S7-1200 CPU與S7-300 CP STEP7 UDP通信

    S7-1200 與 S7-300 CP 之間的以太網通信可以通過 UDP 協議來實現,使用的通信指令是在S7-1200 CPU 側調用通信-
    的頭像 發表于 04-08 10:48 ?2680次閱讀

    S7-1200 CPU與S7-300 CP TIA UDP通信

    S7-1200 與 S7-300 CP 之間的以太網通信可以通過 UDP 協議來實現,使用的通信指令是在S7-1200 CPU 側調用通信-
    的頭像 發表于 04-08 10:49 ?2753次閱讀
    主站蜘蛛池模板: 男女交黄 | 免费大片a一级一级 | 色多多视频在线 | 1024你懂的在线播放欧日韩 | 婷婷综合在线观看丁香 | 久久福利国产 | 免费黄色三级 | 最新看片网址 | 男人的视频网站 | 五月天丁香激情 | 一级做a爰片久久毛片美女图片 | 天天插一插 | 午夜精品在线免费观看 | 精品国产你懂的在线观看 | 亚洲一级毛片免费在线观看 | 丁香综合激情 | 欧美另类色 | 亚洲性天堂 | 绝色村妇的泛滥春情 | 国产三级日本三级韩国三级在线观看 | 国模私拍一区二区三区 | 在线最新版www资源网 | 奇米社区| 性欧美视频在线观看 | www.夜| 日本大片在线看 | 在线午夜视频 | 婷婷色综合网 | 狠狠色噜噜狠狠狠狠狠色综合久久 | 人人免费人人专区 | 视频在线观看免费 | 视频在线观看高清免费看 | 色婷婷激情五月综合 | 午夜.dj高清在线观看免费8 | 91久久青草精品38国产 | 欧美极品在线播放 | 午夜看一级特黄a大片黑 | 亚洲高清色图 | 美女张开腿露尿口给男人亲 | 欧美草比 | 亚洲午夜一区二区三区 |