C語(yǔ)言實(shí)現(xiàn)UDP通信
UDP通信
UDP是一種無(wú)連接的盡最大努力交付的不可靠連接,通信之前無(wú)需先建立連接,自然而然,通信之后也就無(wú)需再釋放連接。
通信的套接字
UDP所采用的通信接口與前面講過的TCP通信接口相同,只是沒有建立連接這一步。
socket()用來(lái)創(chuàng)建套接字,使用 udp 協(xié)議時(shí),選擇數(shù)據(jù)報(bào)服務(wù) SOCK_DGRAM。sendto()用來(lái)發(fā)送數(shù)據(jù),由于 UDP 是無(wú)連接的,每次發(fā)送數(shù)據(jù)都需要指定對(duì)端的地址(IP 和端口)。recvfrom()接收數(shù)據(jù),每次都需要傳給該方法一個(gè)地址結(jié)構(gòu)來(lái)存放發(fā)送端的地址。
recvfrom()可以接收所有客戶端發(fā)送給當(dāng)前應(yīng)用程序的數(shù)據(jù),并不是只能接收某一個(gè)客戶端的數(shù)據(jù)
通信流程
通信過程
客戶端
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <assert.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int main() { ?? ?int sockfd = socket(AF_INET,SOCK_DGRAM,0); ?? ?assert( sockfd != -1 ); ?? ?struct sockaddr_in saddr; ?? ?memset(&saddr,0,sizeof(saddr)); ?? ?saddr.sin_family = AF_INET; ?? ?saddr.sin_port = htons(6000); ?? ?saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); ?? ?while( 1 ) ?? ?{ ?? ?char buff[128] = {0}; ?? ?printf("input:\n"); ?? ?fgets(buff,128,stdin); ?? ?if ( strncmp(buff,"end",3) == 0 ) ?? ?{ ?? ??? ?break; ?? ?} ?? ?sendto(sockfd,buff,strlen(buff),0,(struct ckaddr*)&saddr,sizeof(saddr)); ?? ?memset(buff,0,128); ?? ?int len = sizeof(saddr); ?? ?recvfrom(sockfd,buff,127,0,(struct sockaddr*)&saddr,&len); ?? ?printf("buff=%s\n",buff); ?? ?} ?? ?close(sockfd); }
服務(wù)器端
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <assert.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int main() { ?? ?int sockfd = socket(AF_INET,SOCK_DGRAM,0); ?? ?assert( sockfd != -1 ); ?? ?struct sockaddr_in saddr,caddr; ?? ?memset(&saddr,0,sizeof(saddr)); ?? ?saddr.sin_family = AF_INET; ?? ?saddr.sin_port = htons(6000); ?? ?saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); ?? ?int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr)); ?? ?assert( res != -1 ); ?? ?while( 1 ) ?? ?{ ?? ??? ?int len = sizeof(caddr); ?? ??? ?char buff[128] = {0}; ?? ??? ?recvfrom(sockfd,buff,127,0,(struct sockaddr*)&caddr,&len); ?? ??? ?printf("ip:%s,port:%d,buff=%s\n",inet_ntoa(caddr.sin_addr), ntohs(caddr.sin_port),buff ); ?? ??? ?sendto(sockfd,"ok",2,0,(struct sockaddr*)&caddr,sizeof(caddr)); ?? ?} ?? ?close(sockfd); }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)順序循環(huán)隊(duì)列實(shí)例
大家好,本篇文章主要講的是C語(yǔ)言實(shí)現(xiàn)順序循環(huán)隊(duì)列實(shí)例,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-02-02C語(yǔ)言的入口函數(shù)的實(shí)現(xiàn)
在C語(yǔ)言的世界里,所有的程序都是用函數(shù)來(lái)裝配的,main稱之為主函數(shù),是所有程序運(yùn)行的入口,本文主要介紹了C語(yǔ)言的入口函數(shù),具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01C++學(xué)習(xí)之如何進(jìn)行內(nèi)存資源管理
與java、golang等自帶垃圾回收機(jī)制的語(yǔ)言不同,C++并不會(huì)自動(dòng)回收內(nèi)存,這往往會(huì)導(dǎo)致內(nèi)存泄漏和內(nèi)存溢出等問題,所以掌握C++中的內(nèi)存管理技巧和工具是非常重要的,本文就來(lái)和大家詳細(xì)講講2023-05-05如何在C語(yǔ)言中判斷socket是否已經(jīng)斷開
如果不主動(dòng)關(guān)閉socket的話,系統(tǒng)不會(huì)自動(dòng)關(guān)閉的,除非當(dāng)前進(jìn)程掛掉了,操作系統(tǒng)把占用的socket回收了才會(huì)關(guān)閉。小編今天跟大家簡(jiǎn)單介紹下如何在C語(yǔ)言中判斷socket是否已經(jīng)斷開2019-05-05C++中l(wèi)ist的使用方法及常用list操作總結(jié)
這篇文章主要介紹了C++中l(wèi)ist的使用方法及常用list操作總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-06-06