網(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ī)”
? ? ? ? ? ? ? ? ? ? 點(diǎn)擊“設(shè)置”
? ? ? ? ? ? ? ? ? ? 點(diǎn)擊“網(wǎng)絡(luò)適配器”
? ? ? ? ? ? ? ? ? ? 選擇“橋接模式”
? ? ? ? ? ? ? ? ? ? 點(diǎn)擊“確定”
? ? ? ? ? ? ? ? 3. 將網(wǎng)卡橋接到無線網(wǎng)卡:
? ? ? ? ? ? ? ? ? ? 點(diǎn)擊“編輯”
? ? ? ? ? ? ? ? ? ? 點(diǎn)擊“虛擬網(wǎng)絡(luò)編輯器”
? ? ? ? ? ? ? ? ? ? 點(diǎn)擊“更改設(shè)置”
? ? ? ? ? ? ? ? 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)文章來源:http://www.zghlxwxcb.cn/news/detail-840851.html
#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
文章來源地址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)!