linux UDP伺服器主動傳送資料

2021-10-07 03:01:10 字數 3411 閱讀 8715

tcp udp的連線:

客戶端自己的埠號和ip位址與伺服器是不一樣的

比如使用udp:

埠號是一樣的,客戶端以伺服器為準

客戶端是192.168.1.22,電腦虛擬機器是192.168.1.29

客戶端(powerpc):設定為1.29

埠號:埠號可以寫成不一樣

//mac位址可以亂寫,但不能不寫

unsigned short checksum(unsigned short *buf, int nword);//校驗和函式

int main(int argc, char *ar**)

//1.建立通訊用的原始套接字

int sock_raw_fd = socket(pf_packet, sock_raw, htons(eth_p_all));

//2.根據各種協議首部格式構建傳送資料報

unsigned char send_msg[1024] =

//--------------組mac--------14------

0xb8, 0x88, 0xe3, 0x7c, 0x55, 0xe4, //dst_mac(電腦網口mac位址): b8-88-e3-7c-55-e4

0x00, 0x0e, 0xc6, 0xdd, 0xd1, 0xa1, //src_mac(linux開發板mac位址): 00:0e:c6:dd:d1:a1

// 0x00,0x0c,0x29,0xad,0x9e,0x68, //36

0x08, 0x00, //型別:0x0800 ip協議

//--------------組ip---------20------

0x45, 0x00, 0x00, 0x00, //版本號:4, 首部長度:20位元組, tos:0, --總長度--:

0x00, 0x00, 0x00, 0x00, //16位標識、3位標誌、13位片偏移都設定0

0x80, 17, 0x00, 0x00, //ttl:128、協議:udp(17)、16位首部校驗和

192, 168, 1, 22, //src_ip(電腦網口助手): 10.221.20.11

192, 168, 1, 29, //dst_ip(開發板linux): 10.221.20.10

//--------------組udp--------8+78=86------

0x1f, 0x90, 0x1f, 0x90, //src_port電腦的埠號:0x1f90(8080), dst_port(開發板linux埠號):0x1f90(8080)

0x00, 0x00, 0x00, 0x00, //#--16位udp長度--30個位元組、#16位校驗和

int len = sprintf(send_msg+42, "%s", "this is for the udp test");

if(len % 2 == 1)//判斷len是否為奇數

len++;//如果是奇數,len就應該加1(因為udp的資料部分如果不為偶數需要用0填補)

*((unsigned short *)&send_msg[16]) = htons(20+8+len);//ip總長度 = 20 + 8 + len

*((unsigned short *)&send_msg[14+20+4]) = htons(8+len);//udp總長度 = 8 + len

偽頭部unsigned char pseudo_head[1024] =

//------------udp偽頭部--------12--

192, 168, 1, 29, //src_ip: 10.221.20.11

192, 168, 1, 36, //dst_ip: 10.221.20.10

0x00, 17, 0x00, 0x00, //0,17,#--16位udp長度--20個位元組

*((unsigned short *)&pseudo_head[10]) = htons(8 + len);//為頭部中的udp長度(和真實udp長度是同乙個值)

//4.構建udp校驗和需要的資料報 = udp偽頭部 + udp資料報

memcpy(pseudo_head+12, send_msg+34, 8+len);//--計算udp校驗和時需要加上偽頭部--

//5.對ip首部進行校驗

*((unsigned short *)&send_msg[24]) = htons(checksum((unsigned short *)(send_msg+14),20/2));

//6.--對udp資料進行校驗--

*((unsigned short *)&send_msg[40]) = htons(checksum((unsigned short *)pseudo_head,(12+8+len)/2));

//6.傳送資料

struct sockaddr_ll sll; //原始套接字位址結構

struct ifreq req; //網路介面位址

strncpy(req.ifr_name, "eth0", ifnamsiz); //指定網絡卡名稱

if(-1 == ioctl(sock_raw_fd, siocgifindex, &req)) //獲取網路介面

perror("ioctl");

close(sock_raw_fd);

exit(-1);

/*將網路介面賦值給原始套接字位址結構*/

bzero(&sll, sizeof(sll));

sll.sll_ifindex = req.ifr_ifindex;

len = sendto(sock_raw_fd, send_msg, 14+20+8+len, 0 , (struct sockaddr *)&sll, sizeof(sll));

if(len == -1)

perror("sendto");

return 0;

unsigned short checksum(unsigned short *buf, int nword)

unsigned long sum;

for(sum = 0; nword > 0; nword--)

sum += htons(*buf);

buf++;

sum = (sum>>16) + (sum&0xffff);

sum += (sum>>16);

return ~sum;

伺服器主動推送

1.客戶端輪詢 ajax定時拉取 2.服務端主動推送 websocket 全雙工的,本質是乙個額外的tcp連線,建立和關閉時握手使用的http協議,其他資料傳輸不使用 http協議更加複雜一些,適用於需要進行複雜雙向資料通訊的場景 3.服務端主動推送 sse server send event ht...

SSE 伺服器傳送事件

詳情檢視 sse 伺服器傳送事件 概述傳統的網頁都是瀏覽器向伺服器 查詢 資料,但是很多場合,最有效的方式是伺服器向瀏覽器 傳送 資料。比如,每當收到新的電子郵件,伺服器就向瀏覽器傳送乙個 通知 這要比瀏覽器按時向伺服器查詢 polling 更有效率。自定義事件 function connectti...

linux伺服器下傳送郵件

系統管理人員經常會遇到對於裝置或者任務的預警與通知,通常情況有傳送簡訊 郵件等方式。傳送簡訊一般來說需要有簡訊貓 硬體 或者呼叫libfetion給飛信使用者傳送。本文介紹幾種簡單的傳送郵件的方式。本文環境 ubuntu 10.04 基礎 linux伺服器傳送郵件一般都是基於sendmail進行的,...