国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

嵌入式學(xué)習(xí)第二十五天?。ňW(wǎng)絡(luò)的概念、UDP編程)

這篇具有很好參考價(jià)值的文章主要介紹了嵌入式學(xué)習(xí)第二十五天?。ňW(wǎng)絡(luò)的概念、UDP編程)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

網(wǎng)絡(luò):

? ? 可以用來:數(shù)據(jù)傳輸數(shù)據(jù)共享

1. 網(wǎng)絡(luò)協(xié)議模型:

? ? 1. OSI協(xié)議模型:

應(yīng)用層 實(shí)際收發(fā)的數(shù)據(jù)
表示層 發(fā)送的數(shù)據(jù)是否加密
會(huì)話層 是否建立會(huì)話連接
傳輸層 數(shù)據(jù)傳輸?shù)姆绞剑〝?shù)據(jù)包,流式)
網(wǎng)絡(luò)層 數(shù)據(jù)的路由(如何從一個(gè)局域網(wǎng)到達(dá)另一個(gè)局域網(wǎng))
數(shù)據(jù)鏈路層 局域網(wǎng)下如何通信
物理層 物理介質(zhì)的連接

? ? ? 2. TCP/IP協(xié)議模型:

應(yīng)用層 傳輸?shù)臄?shù)據(jù)
傳輸層 傳輸?shù)姆绞?/td>
網(wǎng)絡(luò)層 數(shù)據(jù)如何從一個(gè)臺(tái)主機(jī)到達(dá)另一臺(tái)主機(jī)
網(wǎng)絡(luò)接口層 物理介質(zhì)的連接
????????1. 應(yīng)用層:

? ? ? ? ? ? ? ?例如有:HTTP? ? ? 超文本傳輸協(xié)議

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? HTTPS? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? FTP? ? ? ? 文件傳輸協(xié)議

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TFTP? ? ? 簡單文本傳輸協(xié)議

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SMTP? ? ?郵件傳輸協(xié)議

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MQTT

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TELNET

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ...

? ? ? ? 2. 傳輸層:

? ? ? ? ? ? ? UDP:用戶數(shù)據(jù)報(bào)協(xié)議

? ? ? ? ? ? ? ? ? ? 特點(diǎn):1. 實(shí)現(xiàn)機(jī)制簡單

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?2. 資源開銷小

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?3. 不安全不可靠

? ? ? ? ? ? ? TCP:傳輸控制協(xié)議

? ? ? ? ? ? ? ? ? ? ? 特點(diǎn):1. 實(shí)現(xiàn)機(jī)制復(fù)雜

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?2. 資源開銷大

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?3. 安全可靠

????????3. 網(wǎng)絡(luò)層:

? ? ? ? ? ? ? IPv4

? ? ? ? ? ? ? IP地址:唯一網(wǎng)絡(luò)中一臺(tái)主機(jī)的標(biāo)號(hào)

? ? ? ? ? ? ? IP地址:網(wǎng)絡(luò)位 + 主機(jī)位

? ? ? ? ? ? ? 子網(wǎng)掩碼:用來標(biāo)識(shí)IP地址的網(wǎng)絡(luò)位和主機(jī)位

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 子網(wǎng)掩碼是1的部分表示IP地址的網(wǎng)絡(luò)位

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 子網(wǎng)掩碼是0的部分表示IP地址的主機(jī)位

? ? ? ? ? ? ? ? 網(wǎng)段號(hào):網(wǎng)絡(luò)位不變,主機(jī)位全位0,表示網(wǎng)段號(hào)

? ? ? ? ? ? ? ? 廣播地址:網(wǎng)絡(luò)位不變,主機(jī)位全為1,表示廣播地址

? ? ? ? ? ? ? ? IP地址類型:

? ? ? ? ? ? ? ? A類:

? ? ? ? ? ? ? ? ? ? ? ? 1.0.0.0? -? 126.255.255.255

? ? ? ? ? ? ? ? ? ? ? ? 子網(wǎng)掩碼:255.0.0.0

? ? ? ? ? ? ? ? ? ? ? ? 管理超大規(guī)模網(wǎng)絡(luò)

? ? ? ? ? ? ? ? ? ? ? ? 私有IP地址:10.0.0.0? -? 10.255.255.255

? ? ? ? ? ? ? ? B類:

? ? ? ? ? ? ? ? ? ? ? ? 128.0.0.0? -? 191.255.255.255

? ? ? ? ? ? ? ? ? ? ? ? 子網(wǎng)掩碼:255.255.0.0

? ? ? ? ? ? ? ? ? ? ? ? 管理大中規(guī)模型網(wǎng)絡(luò)

? ? ? ? ? ? ? ? ? ? ? ? 私有IP地址:172.16.0.0? -? 172.31.255.255

? ? ? ? ? ? ? ? C類:

? ? ? ? ? ? ? ? ? ? ? ? 192.0.0.0? -? 223.255.255.255

? ? ? ? ? ? ? ? ? ? ? ? 子網(wǎng)掩碼:255.255.255.0

? ? ? ? ? ? ? ? ? ? ? ? 管理中小規(guī)模型網(wǎng)絡(luò)

? ? ? ? ? ? ? ? ? ? ? ? 私有IP地址:192.168.0.0? -? 192.168.255.255

? ? ? ? ? ? ? ? D類:

? ? ? ? ? ? ? ? ? ? ? ? 224.0.0.0? -? 239.0.0.0

? ? ? ? ? ? ? ? ? ? ? ? 用于組播

? ? ? ? ? ? ? ? E類:

? ? ? ? ? ? ? ? ? ? ? ? 240.0.0.0? -? 255.255.255.255

? ? ? ? ? ? ? ? ? ? ? ? 用于實(shí)驗(yàn)

????????4. UDP編程:

? ? ? ? ? ? socket套接字(全雙工)編程:

? ? ? ? ? ? 發(fā)端:socket? ->? sendto? ->? close

? ? ? ? ? ? 收端:socket? ->? bind? ->? recvfrom? ->? close

? ? ? ? ? ? 1. 發(fā)端
????????????????1.?socket:
int socket(int domain, int type, int protocol);

? ? ? ? ? ? ? ? ? ? 功能:創(chuàng)建一個(gè)用來通信的文件描述符

? ? ? ? ? ? ? ? ? ? 參數(shù):

? ? ? ? ? ? ? ? ? ? ? ? domain:使用的協(xié)議族 AF_INET(IPv4協(xié)議族)

? ? ? ? ? ? ? ? ? ? ? ? type:套接字類型

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SOCK_STREAM:流式套接字

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SOCK_DGRAM:數(shù)據(jù)報(bào)套接字

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? SOCK_RAW:原始套接字

? ? ? ? ? ? ? ? ? ? ? ? protocol:協(xié)議

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 默認(rèn)為0;

? ? ? ? ? ? ? ? ? ? 返回值:

????????????????????????成功返回文件描述符
????????????????????????失敗返回-1

??????????????? 2. sendto:
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                      const struct sockaddr *dest_addr, socklen_t addrlen);

? ? ? ? ? ? ? ? ? ? 功能:利用套接字向指定地址發(fā)送數(shù)據(jù)信息

????????????????????參數(shù):

? ? ? ? ? ? ? ? ? ? ? ? sockfd:套接字文件描述符

? ? ? ? ? ? ? ? ? ? ? ? buf:發(fā)送數(shù)據(jù)空間首地址

? ? ? ? ? ? ? ? ? ? ? ? len:發(fā)送數(shù)據(jù)的長度

? ? ? ? ? ? ? ? ? ? ? ? flags:屬性默認(rèn)為0

? ? ? ? ? ? ? ? ? ? ? ? dest_addr:目的地址信息存放的空間首地址

? ? ? ? ? ? ? ? ? ? ? ? addrlen:目的地址的長度

struct sockaddr_in {
    sa_family_t    sin_family; /* address family: AF_INET */
    in_port_t      sin_port;   /* port in network byte order */
    struct in_addr sin_addr;   /* internet address */
};

/* Internet address. */
struct in_addr {
    uint32_t       s_addr;     /* address in network byte order */
};

? ? ? ? ? ? ? ? ? ? 返回值:

????????????????????????成功返回實(shí)際發(fā)送字節(jié)數(shù)
????????????????????????失敗返回-1

? ? ? ? ? ? ? ??3. inet_addr:
in_addr_t inet_addr(const char *cp);

? ? ? ? ? ? ? ? ? ? 功能:將字符串IP地址轉(zhuǎn)換為內(nèi)存中的IP地址

????????????????4. htons:
uint16_t htons(uint16_t hostshort);

? ? ? ? ? ? ? ? ? ? 功能:將本地字節(jié)序轉(zhuǎn)換為網(wǎng)絡(luò)的大端字節(jié)序

? ? ? ? ? ? 練習(xí):

? ? ? ? ? ? ? ? 1. 編寫程序?qū)崿F(xiàn)從終端接收字符串發(fā)送給windows軟件調(diào)試助手,并接收軟件助手的回復(fù),顯示在終端屏幕上

#include "head.h"

int main(void)
{
	int sockfd = 0;
	ssize_t nsize = 0;
	char tmpbuff[1024] = {0};
	struct sockaddr_in recvaddr;

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(sockfd == -1)
	{
		perror("fail to socket");
		return -1;
	}
	
	gets(tmpbuff);


	recvaddr.sin_family = AF_INET;
	recvaddr.sin_port = htons(50000);
	recvaddr.sin_addr.s_addr = inet_addr("192.168.1.162");
	
	bind(sockfd, (struct sockaddr *)&recvaddr, sizeof(&recvaddr));

	nsize = sendto(sockfd, tmpbuff, strlen(tmpbuff), 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
	if(nsize == -1)
	{
		perror("fail to sendto");
		return -1;
	}

	printf("成功發(fā)送 %ld 字節(jié)!\n", nsize);

	
	memset(tmpbuff, 0, sizeof(tmpbuff));
	nsize = recvfrom(sockfd, tmpbuff, sizeof(tmpbuff), 0, (struct sockaddr *)&recvaddr, (socklen_t *)sizeof(&recvaddr));
	printf("%s\n",tmpbuff);

	close(sockfd);

	return 0;
}
? ? ? ? ? ???2. 收端
????????????????1. recvfrom:
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
                        struct sockaddr *src_addr, socklen_t *addrlen);

? ? ? ? ? ? ? ? ? ? 功能:從套接字中接收數(shù)據(jù)

? ? ? ? ? ? ? ? ? ? 參數(shù):

? ? ? ? ? ? ? ? ? ? ? ? sockfd:套接字文件描述符

? ? ? ? ? ? ? ? ? ? ? ? buf:存放數(shù)據(jù)空間首地址

? ? ? ? ? ? ? ? ? ? ? ? flags:屬性,默認(rèn)為0

? ? ? ? ? ? ? ? ? ? ? ? src_addr:存放IP地址信息的空間首地址

? ? ? ? ? ? ? ? ? ? ? ? addlen:存放接收到IP地址大小空間的首地址

? ? ? ? ? ? ? ? ? ? 返回值:

????????????????????????成功返回實(shí)際接收字節(jié)數(shù)
????????????????????????失敗返回-1?

? ? ? ? ? ? ? ? 2. 修改虛擬機(jī)到橋接模式:

? ? ? ? ? ? ? ? ? ? 點(diǎn)擊“虛擬機(jī)”

嵌入式學(xué)習(xí)第二十五天?。ňW(wǎng)絡(luò)的概念、UDP編程),學(xué)習(xí)

? ? ? ? ? ? ? ? ? ? 點(diǎn)擊“設(shè)置”

嵌入式學(xué)習(xí)第二十五天?。ňW(wǎng)絡(luò)的概念、UDP編程),學(xué)習(xí)

? ? ? ? ? ? ? ? ? ? 點(diǎn)擊“網(wǎng)絡(luò)適配器”

? ? ? ? ? ? ? ? ? ? 選擇“橋接模式”

? ? ? ? ? ? ? ? ? ? 點(diǎn)擊“確定”

嵌入式學(xué)習(xí)第二十五天?。ňW(wǎng)絡(luò)的概念、UDP編程),學(xué)習(xí)

? ? ? ? ? ? ? ? 3. 將網(wǎng)卡橋接到無線網(wǎng)卡:

? ? ? ? ? ? ? ? ? ? 點(diǎn)擊“編輯”

嵌入式學(xué)習(xí)第二十五天?。ňW(wǎng)絡(luò)的概念、UDP編程),學(xué)習(xí)

? ? ? ? ? ? ? ? ? ? 點(diǎn)擊“虛擬網(wǎng)絡(luò)編輯器”

嵌入式學(xué)習(xí)第二十五天!(網(wǎng)絡(luò)的概念、UDP編程),學(xué)習(xí)

? ? ? ? ? ? ? ? ? ? 點(diǎn)擊“更改設(shè)置”

嵌入式學(xué)習(xí)第二十五天!(網(wǎng)絡(luò)的概念、UDP編程),學(xué)習(xí)

? ? ? ? ? ? ? ? 4. 在Ubuntu中重啟網(wǎng)絡(luò)服務(wù):
sudo /etc/init.d/networking restart 
? ? ? ? ? ? ? ? 5. 通過ifconfig查看虛擬機(jī)IP地址
? ? ? ? ? ? ? ? 6. bind:
int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);

? ? ? ? ? ? ? ? ? ? 功能:在套接字上綁定一個(gè)IP地址和端口號(hào)

? ? ? ? ? ? ? ? ? ? 參數(shù):

? ? ? ? ? ? ? ? ? ? ? ? sockfd:套接字文件描述符

? ? ? ? ? ? ? ? ? ? ? ? addr:綁定IP地址空間首地址

? ? ? ? ? ? ? ? ? ? ? ? addrlen:綁定IP地址的長度

? ? ? ? ? ? ? ? ? ? 返回值:

????????????????????????成功返回0?
????????????????????????失敗返回-1?

? ? ? ? ? ? 3. UDP需要注意的細(xì)節(jié)點(diǎn):

? ? ? ? ? ? ? ? 1. UDP是無連接,發(fā)端退出,收端沒有任何影響

? ? ? ? ? ? ? ? 2. UDP發(fā)送數(shù)據(jù)上限,最好不要超過1500個(gè)字節(jié)

? ? ? ? ? ? ? ? 3. UDP是不安全不可靠的,連續(xù)且快速的傳輸數(shù)據(jù)容易產(chǎn)生數(shù)據(jù)丟失

? ? ? ? ? ? 4. wireshark

? ? ? ? ? ? ? ? 可以通過wireshark抓包工具來查看收發(fā)的數(shù)據(jù)

? ? ? ? ? ? ? ? 操作流程:

? ? ? ? ? ? ? ? ? ? 1. 打開wireshark:

sudo wireshark

? ? ? ? ? ? ? ? ? ? 2. 選擇抓取數(shù)據(jù)包的網(wǎng)卡:any

? ? ? ? ? ? ? ? ? ? 3. 執(zhí)行通信的代碼

? ? ? ? ? ? ? ? ? ? 4. 停止通信

? ? ? ? ? ? ? ? ? ? 5. 設(shè)定過濾條件

? ? ? ? ? ? ? ? ? ? ? ? ip.addr == IP地址? :通過IP地址查找

? ? ? ? ? ? ? ? ? ? ? ? udp? ? ? ? ? ? ? ? ? ? ? ? :通過傳輸方式udp查找

? ? ? ? ? ? ? ? ? ? ? ? tcp? ? ? ? ? ? ? ? ? ? ? ? ?:通過傳輸方式tcp查找

? ? ? ? ? ? ? ? ? ? ? ? udp.port == 端口號(hào):通過端口號(hào)查找

? ? ? ? ? ? 5. UDP包頭長度:8個(gè)字節(jié)

? ? ? ? ? ? ? ? 源端口號(hào)(2個(gè)字節(jié))

? ? ? ? ? ? ? ? 目的端口號(hào)(2個(gè)字節(jié))

? ? ? ? ? ? ? ? 長度(2個(gè)字節(jié))

? ? ? ? ? ? ? ? 檢驗(yàn)和(2個(gè)字節(jié))

? ? ? ? ? ? 練習(xí):

? ? ? ? ? ? ? ? 要求在不同主機(jī)中編寫兩個(gè)程序,實(shí)現(xiàn)全雙工聊天功能

? ? ? ? ? ? ? ? 1. 進(jìn)入軟件后接收當(dāng)前用戶的昵稱

? ? ? ? ? ? ? ? 2. 顯示的格式為對(duì)方用戶昵稱 (對(duì)方IP:對(duì)方端口) > 接收到的內(nèi)容

? ? ? ? ? ? ? ? 3. 用戶輸入“.quit”退出聊天

? ? ? ? ? ? ? ? 4. 網(wǎng)絡(luò)通信時(shí)收發(fā)結(jié)構(gòu)體

struct person 
{
    char name[32];
    char text[512];
};
#include "head.h"

int sockfd = 0;
ssize_t nsize = 0;
struct sockaddr_in tmpaddr;
struct sockaddr_in sendaddr;
socklen_t addrlen = sizeof(tmpaddr);

struct person
{
	char name[32];
	char text[512];
};

pthread_t tid_recv;
pthread_t tid_send;

void *RecvInfo(void *arg)
{
	struct person user;
	while(1)
	{
		memset(&user, 0, sizeof(user));
		nsize = recvfrom(sockfd, &user, sizeof(user), 0, (struct sockaddr *)&tmpaddr, &addrlen);
		if(nsize == -1)
		{
			perror("fail to recvfrom");
			return NULL;
		}
		printf("%s %s : %d > %s\n", user.name, inet_ntoa(tmpaddr.sin_addr), ntohs(tmpaddr.sin_port), user.text);
		if(!strcmp(user.text, ".quit"))
		{
			break;
		}
	}
	pthread_cancel(tid_send);
	return NULL;
}

void *SendInfo(void *arg)
{
	struct person user;
	while(1)
	{
		memset(&user, 0, sizeof(user));
		scanf("%s", user.name);
		scanf("%s", user.text);
		nsize = sendto(sockfd, &user, sizeof(user), 0, (struct sockaddr *)&sendaddr, sizeof(sendaddr));
		if(nsize == -1)
		{
			perror("fail to sendto");
			return NULL;
		}
		printf("success send %ld byte\n", nsize);
		if(!strcmp(user.text, ".quit"))
		{
			break;
		}
	}
	pthread_cancel(tid_recv);
	
	return NULL;
}

int main(void)
{
	struct sockaddr_in recvaddr;

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(sockfd == -1)
	{
		perror("fail to socket");
		return -1;
	}
	
	recvaddr.sin_family = AF_INET;
	recvaddr.sin_port = htons(30000);
	recvaddr.sin_addr.s_addr = inet_addr("192.168.1.153");
	bind(sockfd, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
	
	sendaddr.sin_family = AF_INET;
	sendaddr.sin_port = htons(30000);
	sendaddr.sin_addr.s_addr = inet_addr("192.168.1.152");
	
	pthread_create(&tid_recv, NULL, RecvInfo, NULL);
	pthread_create(&tid_send, NULL, SendInfo, NULL);

	pthread_join(tid_recv, NULL);
	pthread_join(tid_send, NULL);


	close(sockfd);

	return 0;

}
????????5. UDP項(xiàng)目練習(xí):

? ? ? ? 題目:基于UDP實(shí)現(xiàn)直播間聊天的功能:

? ? ? ? 需求:

? ? ? ? ? ? ? ? 軟件劃分為用戶客戶端和主播服務(wù)端兩個(gè)軟件client.c和server.c

? ? ? ? ? ? ? ? 用戶客戶端負(fù)責(zé):

? ? ? ? ? ? ? ? ? ? ? ? 1.接收用戶的昵稱
????????????????????????2.接收用戶輸入的信息,能夠?qū)⑿畔l(fā)送給服務(wù)端
????????????????????????3.接收服務(wù)端回復(fù)的數(shù)據(jù)信息,并完成顯示

? ? ? ? ? ? ? ? 主播服務(wù)端負(fù)責(zé):

? ? ? ? ? ? ? ? ? ? ? ? 1.對(duì)所有加入直播間的用戶的IP地址和端口實(shí)現(xiàn)管理(加入、退出)
????????????????????????2.當(dāng)有新的客戶端加入時(shí),能夠向所有客戶端提示:"歡迎 XXX 用戶進(jìn)入直播間"
? ? ? ? ????????????????3.當(dāng)有客戶端退出時(shí),能夠向所有客戶端提示:"XXX 離開直播間"
? ? ? ? ????????????????4.能夠?qū)崿F(xiàn)客戶端聊天內(nèi)容的轉(zhuǎn)發(fā),當(dāng)某個(gè)客戶端發(fā)送聊天信息時(shí),能夠?qū)⒃撔畔⑥D(zhuǎn)給除了該用戶之外聊天室內(nèi)所有其余客戶端用戶

client.c

#include "head.h"

int sockfd = 0;
char name[32];
struct sockaddr_in recvaddr;
pthread_t tid_send;
pthread_t tid_recv;

void *SendMsg(void *arg)
{
	struct msgbuf sendmsg;
	ssize_t nsize = 0;
	while(1)
	{
		memset(&sendmsg, 0, sizeof(sendmsg)); 
		sendmsg.type = USER_TYPE_CHAT;
		sprintf(sendmsg.name, "%s", name);
		gets(sendmsg.text);
		if(strcmp(sendmsg.text,".quit") == 0)
		{
			sendmsg.type = USER_TYPE_OUT;
		}
		nsize = sendto(sockfd, &sendmsg, sizeof(sendmsg), 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
		if(nsize == -1)
		{
			perror("fail to sendto");
			return NULL;
		}
		if(sendmsg.type == USER_TYPE_OUT)
		{
			break;
		}
	}
	pthread_cancel(tid_recv);

	return NULL;
}

void *RecvMsg(void *arg)
{
	struct msgbuf recvmsg;
	ssize_t nsize = 0;

	while(1)
	{
		nsize = recvfrom(sockfd, &recvmsg, sizeof(recvmsg), 0, NULL, NULL);
		if(nsize == -1)
		{
			perror("fail to recvfrom");
			return NULL;
		}
		if(recvmsg.type == USER_TYPE_CHAT)
		{
			printf("%s>%s\n", recvmsg.name, recvmsg.text);
		}
		if(recvmsg.type == USER_TYPE_OUT)
		{
			break;
		}
	}
	
	return NULL;
}

int main(void)
{
	ssize_t nsize = 0;
	struct msgbuf sendmsg; 


	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(sockfd == -1)
	{
		perror("fail to socket");
		return -1;
	}
	
	printf("請輸入你的名字:\n");
	gets(name);
	
	memset(&sendmsg, 0, sizeof(sendmsg));
	sendmsg.type = USER_TYPE_INT;
	sprintf(sendmsg.name, "%s", name);

	recvaddr.sin_family = AF_INET;
	recvaddr.sin_port = htons(SERVER_PORT);
	recvaddr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
	nsize = sendto(sockfd, &sendmsg, sizeof(sendmsg), 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr));
	if(nsize == -1)
	{
		perror("fail to sendto");
		return -1;
	}

	pthread_create(&tid_send, NULL, SendMsg, NULL);
	pthread_create(&tid_recv, NULL, RecvMsg, NULL);

	pthread_join(tid_send, NULL);
	pthread_join(tid_recv, NULL);

	close(sockfd);
}

server.c

#include "head.h"

int main(void)
{
	int sockfd = 0;
	ssize_t nsize = 0;
	ssize_t size = 0;
	struct sockaddr_in serveraddr;
	
	struct address useraddr[100];
	struct sockaddr_in userinfo;
	socklen_t addrlen = 0;
	addrlen = sizeof(userinfo);

	struct msgbuf recvuser;
	int i = 0;

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(sockfd == -1)
	{
		perror("fail to socket");
		return -1;
	}
	
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = htons(SERVER_PORT);
	serveraddr.sin_addr.s_addr = inet_addr(SERVER_ADDR);
	bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
	
	memset(useraddr, 0, sizeof(useraddr));

	while(1)
	{
		memset(&recvuser, 0, sizeof(recvuser));
		memset(&userinfo, 0, sizeof(userinfo));
		nsize = recvfrom(sockfd, &recvuser, sizeof(recvuser), 0, (struct sockaddr *)&userinfo, &addrlen);
		if(nsize == -1)
		{
			return -1;
		}
		if(recvuser.type == USER_TYPE_INT)
		{
			for(i = 0; i < 100; i++)
			{
				if(useraddr[i].mark == 1)
				{
					continue;
				}
				else if(useraddr[i].mark == 0)
				{
					useraddr[i].mark = 1;
					useraddr[i].cltaddr.sin_family = AF_INET;
					useraddr[i].cltaddr.sin_port = userinfo.sin_port;
					useraddr[i].cltaddr.sin_addr.s_addr = userinfo.sin_addr.s_addr;
					printf("歡迎用戶:%s來到直播間!\n", recvuser.name);
					break;
				}
			}
		}
		else if(recvuser.type == USER_TYPE_OUT)
		{
			for(i = 0; i < 100; i++)
			{
				if(memcmp(&useraddr[i].cltaddr, &userinfo, sizeof(userinfo)) == 0)
				{
						useraddr[i].mark = 0;
						printf("用戶:%s離開直播間!\n", recvuser.name);
				}
			}
		}
		else if(recvuser.type == USER_TYPE_CHAT)
		{
			printf("%s(%s:%d)>%s\n", recvuser.name, inet_ntoa(userinfo.sin_addr), ntohs(userinfo.sin_port), recvuser.text);
			for(i = 0; i < 100; i++)
			{
				if(useraddr[i].mark != 0)
				{
					size = sendto(sockfd, &recvuser, sizeof(recvuser), 0, (struct sockaddr *)&useraddr[i].cltaddr, sizeof(useraddr[i].cltaddr));
					if(size == -1)
					{
						perror("fail to sendto");
						return -1;
					}
				}
			}
		}
	}	
	close(sockfd);

	return 0;
}

在這里head.h中定義了兩個(gè)結(jié)構(gòu)體,已經(jīng)定義了客戶發(fā)過來的狀態(tài)

#ifndef _HEAD_H_
#define _HEAD_H_

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <time.h>
#include <pwd.h>
#include <grp.h>
#include <pthread.h>
#include <semaphore.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>

struct msgbuf
{
	int type;
	char name[32];
	char text[512];
};

struct address
{
	struct sockaddr_in cltaddr;
	int mark;
};

#define USER_TYPE_INT  100
#define USER_TYPE_OUT   200
#define USER_TYPE_CHAT  300

#define SERVER_ADDR  "192.168.1.162"
#define SERVER_PORT  5000

#endif

嵌入式學(xué)習(xí)第二十五天?。ňW(wǎng)絡(luò)的概念、UDP編程),學(xué)習(xí)文章來源地址http://www.zghlxwxcb.cn/news/detail-840851.html

到了這里,關(guān)于嵌入式學(xué)習(xí)第二十五天?。ňW(wǎng)絡(luò)的概念、UDP編程)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 嵌入式學(xué)習(xí)day34 網(wǎng)絡(luò)

    嵌入式學(xué)習(xí)day34 網(wǎng)絡(luò)

    TCP包頭: 1.序號(hào):發(fā)送端發(fā)送數(shù)據(jù)包的編號(hào) 2.確認(rèn)號(hào):已經(jīng)確認(rèn)接收到的數(shù)據(jù)的編號(hào)(只有當(dāng)ACK為1時(shí),確認(rèn)號(hào)才有用) TCP為什么安全可靠: 1.在通信前建立三次握手連接 ? ? SYN ? ? SYN+ACK? ? ? ACK? 2.在通信過程中通過序列號(hào)和確認(rèn)號(hào)保障數(shù)據(jù)傳輸?shù)耐暾?? ? 本次發(fā)送序列號(hào):上次收

    2024年03月10日
    瀏覽(30)
  • 網(wǎng)絡(luò)-IP地址(嵌入式學(xué)習(xí))

    網(wǎng)絡(luò)-IP地址(嵌入式學(xué)習(xí))

    IP地址是Internet中主機(jī)的標(biāo)識(shí) IP地址(Internet Protocol Address 互聯(lián)網(wǎng)國際地址)是一種在Internet上的給主機(jī)編址的方式,它主要是為互聯(lián)網(wǎng)上的每一個(gè)網(wǎng)絡(luò)和每一臺(tái)主機(jī)分配一個(gè)邏輯地址,以此來屏蔽物理地址的差異。 IP地址為32位(IPv4)或者128位(IPv6) IPV4地址由網(wǎng)絡(luò)號(hào)與主機(jī)

    2023年04月19日
    瀏覽(25)
  • 嵌入式學(xué)習(xí)-網(wǎng)絡(luò)編程-Day5

    嵌入式學(xué)習(xí)-網(wǎng)絡(luò)編程-Day5

    1.使用poll實(shí)現(xiàn)TCP服務(wù)器的并發(fā) 使用select實(shí)現(xiàn)TCP客戶端的并發(fā)

    2024年01月20日
    瀏覽(34)
  • 《嵌入式入門-模電基礎(chǔ)》第二階段

    《嵌入式入門-模電基礎(chǔ)》第二階段

    科技的不斷發(fā)展,給計(jì)算機(jī)行業(yè)帶來了很多機(jī)會(huì), 嵌 入式開發(fā)的前景也越來越廣闊, 過去的嵌入式是:電器、機(jī)械、交通設(shè)備。現(xiàn)在的嵌入式是:手機(jī)、智能家居、物聯(lián)網(wǎng)、新能源、新基建、芯片...... 隨著國家政策的傾斜,實(shí)業(yè)發(fā)展的需求, 市場對(duì)嵌入式人才的“渴求”

    2024年02月16日
    瀏覽(25)
  • 【小黑嵌入式系統(tǒng)第二課】嵌入式系統(tǒng)的概述(二)——外圍設(shè)備、處理器、ARM

    【小黑嵌入式系統(tǒng)第二課】嵌入式系統(tǒng)的概述(二)——外圍設(shè)備、處理器、ARM

    板級(jí)支持包(BSP) 是商用嵌入式操作系統(tǒng)實(shí)現(xiàn)可移植性所采用的一種方案,是硬件抽象層的一種實(shí)現(xiàn)。BSP是介于硬件和操作系統(tǒng)中驅(qū)動(dòng)層程序之間的一層,有時(shí)也可認(rèn)為屬于操作系統(tǒng)一部分。BSP實(shí)現(xiàn)了對(duì)操作系統(tǒng)的支持,為上層的驅(qū)動(dòng)程序提供訪問硬件設(shè)備的函數(shù)包。 BSP隔離了

    2024年04月17日
    瀏覽(25)
  • 嵌入式培訓(xùn)機(jī)構(gòu)四個(gè)月實(shí)訓(xùn)課程筆記(完整版)-Linux系統(tǒng)編程第五天-Linux消息共享內(nèi)存(物聯(lián)技術(shù)666)

    ?更多配套資料CSDN地址:點(diǎn)贊+關(guān)注,功德無量。更多配套資料,歡迎私信。 物聯(lián)技術(shù)666_嵌入式C語言開發(fā),嵌入式硬件,嵌入式培訓(xùn)筆記-CSDN博客 物聯(lián)技術(shù)666擅長嵌入式C語言開發(fā),嵌入式硬件,嵌入式培訓(xùn)筆記,等方面的知識(shí),物聯(lián)技術(shù)666關(guān)注機(jī)器學(xué)習(xí),arm開發(fā),物聯(lián)網(wǎng),嵌入式硬件,單

    2024年02月01日
    瀏覽(22)
  • 嵌入式培訓(xùn)機(jī)構(gòu)四個(gè)月實(shí)訓(xùn)課程筆記(完整版)-C++和QT編程第五天-Qt基礎(chǔ)(物聯(lián)技術(shù)666)

    嵌入式培訓(xùn)機(jī)構(gòu)四個(gè)月實(shí)訓(xùn)課程筆記(完整版)-C++和QT編程第五天-Qt基礎(chǔ)(物聯(lián)技術(shù)666)

    鏈接:https://pan.baidu.com/s/1HENCN2TrrxRvvkAmPxonfg?pwd=1688 提取碼:1688 QT常用快捷鍵 ctrl+f? 高亮查找; ctrl+s? 保存 ctrl+/? 注銷 F1?? ?? 對(duì)指定的文件幫助顯示,連續(xù)2下,全屏顯示 ctrl+鼠標(biāo)左鍵? 跳轉(zhuǎn)到目標(biāo)內(nèi)容 label:改變前景和背景是window 和windowtext? 背景色必須勾選autofillbackgro

    2024年01月20日
    瀏覽(51)
  • 【嵌入式學(xué)習(xí)】網(wǎng)絡(luò)通信基礎(chǔ)-項(xiàng)目篇:簡單UDP聊天室

    【嵌入式學(xué)習(xí)】網(wǎng)絡(luò)通信基礎(chǔ)-項(xiàng)目篇:簡單UDP聊天室

    源碼已在GitHub開源:0clock/LearnEmbed-projects/chat 客戶端功能: 上線發(fā)送登錄的用戶名[yes] 發(fā)送消息和接收消息[yes] quit退出 服務(wù)器端功能: 統(tǒng)計(jì)用戶上線信息,放入鏈表中[yes] 接收用戶信息并給其他用戶發(fā)送消息[yes] 服務(wù)器也支持給所有用戶群發(fā)消息[yes] 接收下線提醒

    2024年01月25日
    瀏覽(88)
  • 第二章 嵌入式系統(tǒng)硬件基礎(chǔ)知識(shí)

    第二章 嵌入式系統(tǒng)硬件基礎(chǔ)知識(shí)

    (1)信號(hào)特性 用 “ 邏輯真 ” “ 1 ” 或 “ 確定 ”來表示 高電平 用?“?邏輯假?”?“?0?”?或?“?不確定?”來表示 低電平 1和0稱為 互補(bǔ)信號(hào) (2)信號(hào)轉(zhuǎn)換 1、數(shù)字集成電路的分類 ????????按照開關(guān)元件的不同,數(shù)字集成電路分為兩大類:一類是 雙極型集成電路

    2024年01月21日
    瀏覽(30)
  • SpringBoot源碼解讀與原理分析(二十七)嵌入式Tomcat

    SpringBoot源碼解讀與原理分析(二十七)嵌入式Tomcat

    當(dāng)Web應(yīng)用需要部署運(yùn)行時(shí),傳統(tǒng)的做法是將項(xiàng)目打包成war包,然后部署到外置的Web容器中(如最常用的Tomcat容器)。 SpringBoot的一大重要特性是支持嵌入式Web容器,基于SpringBoot的Web應(yīng)用僅憑一個(gè)單獨(dú)的jar包即可獨(dú)立運(yùn)行。 8.1.1 嵌入式Tomcat與普通Tomcat 嵌入式Tomcat是一種可以嵌

    2024年02月22日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包