新聞中心
在日常開發(fā)過(guò)程中,我們常常需要進(jìn)行進(jìn)程間通信。其中,網(wǎng)絡(luò)通信是最常用的一種方式。而在網(wǎng)絡(luò)通信中,UDP協(xié)議被廣泛使用。本文將詳細(xì)介紹在Linux環(huán)境下,如何使用UDP協(xié)議進(jìn)行本地通信。

創(chuàng)新互聯(lián)建站是一家朝氣蓬勃的網(wǎng)站建設(shè)公司。公司專注于為企業(yè)提供信息化建設(shè)解決方案。從事網(wǎng)站開發(fā),網(wǎng)站制作,網(wǎng)站設(shè)計(jì),網(wǎng)站模板,微信公眾號(hào)開發(fā),軟件開發(fā),微信小程序開發(fā),10余年建站對(duì)成都護(hù)欄打樁機(jī)等多個(gè)行業(yè),擁有豐富的網(wǎng)站推廣經(jīng)驗(yàn)。
一、UDP協(xié)議簡(jiǎn)介
UDP(User Datagram Protocol,用戶報(bào)文協(xié)議)是一種無(wú)連接的協(xié)議。它不會(huì)建立連接,直接將數(shù)據(jù)報(bào)文發(fā)送至目的IP地址和端口號(hào)。UDP不區(qū)分客戶端和服務(wù)器,所以在通信時(shí),要先確定好通信的雙方的IP地址和端口號(hào)。UDP相對(duì)于TCP更加輕量級(jí),傳輸效率更高,但是其不具有可靠性。數(shù)據(jù)報(bào)文可能會(huì)丟失、重復(fù)、亂序等,這些問(wèn)題需要應(yīng)用程序自行處理。
二、UDP協(xié)議的優(yōu)缺點(diǎn)
1. 優(yōu)點(diǎn)
(1)傳輸效率:UDP使用無(wú)連接傳輸,不需要建立和斷開連接,數(shù)據(jù)報(bào)文的傳輸效率高;
(2)適合數(shù)據(jù)量小的傳輸:由于UDP協(xié)議沒有包頭和包尾,因此數(shù)據(jù)報(bào)文更加緊湊,適合傳輸數(shù)據(jù)量小的信息。
2. 缺點(diǎn)
(1)不可靠:UDP協(xié)議不提供可靠性,數(shù)據(jù)報(bào)文可能丟失、重復(fù)、亂序等;
(2)應(yīng)用程序自行處理:UDP協(xié)議不提供順序控制和重傳機(jī)制,這些問(wèn)題需要應(yīng)用程序自行處理;
(3)難以控制擁塞:UDP協(xié)議不提供擁塞控制機(jī)制,對(duì)網(wǎng)絡(luò)帶寬的利用率不夠高。
三、UDP協(xié)議的使用
1. 創(chuàng)建Socket
要使用UDP協(xié)議進(jìn)行本地通信,首先需要?jiǎng)?chuàng)建Socket。Socket是應(yīng)用程序和網(wǎng)絡(luò)之間的一個(gè)接口,它是數(shù)據(jù)傳輸?shù)耐ǖ馈?/p>
int fd = socket(AF_INET, SOCK_DGRAM, 0);
其中,之一個(gè)參數(shù)AF_INET表示要使用IPv4協(xié)議,第二個(gè)參數(shù)SOCK_DGRAM表示要使用UDP協(xié)議,第三個(gè)參數(shù)0表示由系統(tǒng)自動(dòng)選擇使用的協(xié)議。
2. 綁定IP和端口號(hào)
要進(jìn)行本地通信,需要將本地的IP和端口號(hào)與Socket綁定。
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(8888);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(fd, (struct sockaddr*)&addr, sizeof(addr));
其中,之一個(gè)參數(shù)fd是Socket的文件描述符,第二個(gè)參數(shù)是一個(gè)指向sockaddr_in結(jié)構(gòu)體的指針,用于存儲(chǔ)綁定的IP和端口號(hào),第三個(gè)參數(shù)用于指定sockaddr_in結(jié)構(gòu)體的大小。
3. 發(fā)送數(shù)據(jù)報(bào)文
要發(fā)送數(shù)據(jù)報(bào)文,需要指定目標(biāo)IP地址和端口號(hào),將數(shù)據(jù)寫入Socket。
struct sockaddr_in dest_addr;
dest_addr.sin_family = AF_INET;
dest_addr.sin_port = htons(8888);
inet_pton(AF_INET, “127.0.0.1”, &dest_addr.sin_addr);
sendto(fd, buf, len, 0, (struct sockaddr*)&dest_addr, sizeof(dest_addr));
其中,之一個(gè)參數(shù)fd是Socket的文件描述符,第二個(gè)參數(shù)buf是要發(fā)送的數(shù)據(jù)緩沖區(qū),第三個(gè)參數(shù)len是要發(fā)送的數(shù)據(jù)長(zhǎng)度,第四個(gè)參數(shù)0表示不需要特殊的控制,第五個(gè)參數(shù)是一個(gè)指向sockaddr_in結(jié)構(gòu)體的指針,用于指定目標(biāo)IP地址和端口號(hào),第六個(gè)參數(shù)用于指定sockaddr_in結(jié)構(gòu)體的大小。
4. 接收數(shù)據(jù)報(bào)文
要接收數(shù)據(jù)報(bào)文,需要先創(chuàng)建緩沖區(qū),然后等待接收數(shù)據(jù)。
char buf[1024];
struct sockaddr_in src_addr;
socklen_t src_len = sizeof(src_addr);
recvfrom(fd, buf, sizeof(buf), 0, (struct sockaddr*)&src_addr, &src_len);
其中,之一個(gè)參數(shù)fd是Socket的文件描述符,第二個(gè)參數(shù)buf是用于接收數(shù)據(jù)的緩沖區(qū),第三個(gè)參數(shù)sizeof(buf)表示緩沖區(qū)的大小,第四個(gè)參數(shù)0表示不需要特殊的控制,第五個(gè)參數(shù)是一個(gè)指向sockaddr_in結(jié)構(gòu)體的指針,用于存儲(chǔ)發(fā)送數(shù)據(jù)報(bào)文方的IP和端口號(hào),第六個(gè)參數(shù)用于指定sockaddr_in結(jié)構(gòu)體的大小。
四、
本文詳細(xì)介紹了在Linux環(huán)境下,如何使用UDP協(xié)議進(jìn)行本地通信。UDP協(xié)議是一種無(wú)連接的協(xié)議,傳輸效率高,適合傳輸數(shù)據(jù)量小的信息。但由于其不提供可靠性和擁塞控制機(jī)制,需要應(yīng)用程序自行處理。
在使用UDP協(xié)議進(jìn)行本地通信時(shí),需要?jiǎng)?chuàng)建Socket,綁定IP和端口號(hào),發(fā)送數(shù)據(jù)報(bào)文和接收數(shù)據(jù)報(bào)文。在發(fā)送和接收數(shù)據(jù)報(bào)文時(shí),需要指定目標(biāo)IP地址和端口號(hào),以及緩沖區(qū)大小。這些細(xì)節(jié)需要開發(fā)人員掌握,才能順利地進(jìn)行本地通信。
相關(guān)問(wèn)題拓展閱讀:
- UDP和Socket通信步驟
UDP和Socket通信步驟
這是在網(wǎng)上找到的,希望對(duì)你有所幫助。
sockets(套接數(shù)神字)編程有三種,流式套接字(SOCK_STREAM),數(shù)據(jù)報(bào)套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);
WINDOWS環(huán)境下TCP/UDP編程步驟:
1. 基于褲畢巖TCP的socket編程是采用的流式套接字。
在這個(gè)程序中,將兩個(gè)工程添加到一個(gè)工作區(qū)。要鏈接一個(gè)ws2_32.lib的庫(kù)文件。
服務(wù)器端編程的步驟:
1:加載套接字庫(kù),創(chuàng)建套接字(WSAStartup()/socket());
2:綁定套接字到一個(gè)IP地址和一個(gè)端口上(bind());
3:將套接字設(shè)置為監(jiān)聽模式等待連接請(qǐng)求(listen());
4:請(qǐng)求到來(lái)后,接受連接請(qǐng)求,返回一個(gè)新的對(duì)應(yīng)于此次連接的套接字(accept());
5:用返回的套接字和客戶端進(jìn)行通信(send()/recv());
6:返回,等待另一連接請(qǐng)求;
7:關(guān)閉套接字,關(guān)閉加載的套接字庫(kù)(closesocket()/WSACleanup())。
服務(wù)器端代碼如下:
#include
#include
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
listen(sockSrv,5);
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
while(1)
{
SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
char sendBuf;
sprintf(sendBuf,”Welcome %s to here!”,inet_ntoa(addrClient.sin_addr));
send(sockConn,sendBuf,strlen(sendBuf)+1,0);
char recvBuf;
recv(sockConn,recvBuf,50,0);
printf(“%s\n”,recvBuf);
closesocket(sockConn);
}
}
客戶端編程的步驟:
1:加載套接字庫(kù),創(chuàng)建套接字(WSAStartup()/socket());
2:向服務(wù)器發(fā)出胡御連接請(qǐng)求(connect());
3:和服務(wù)器端進(jìn)行通信(send()/recv());
4:關(guān)閉套接字,關(guān)閉加載的套接字庫(kù)(closesocket()/WSACleanup())。
客戶端的代碼如下:
#include
#include
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 ) {
WSACleanup( );
return;
}
SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr(“127.0.0.1”);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(6000);
connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
char recvBuf;
recv(sockClient,recvBuf,50,0);
printf(“%s\n”,recvBuf);
send(sockClient,”hello”,strlen(“hello”)+1,0);
closesocket(sockClient);
WSACleanup();
}
2.基于UDP的socket編程是采用的數(shù)據(jù)報(bào)套接字。
在這個(gè)程序中,將兩個(gè)工程添加到一個(gè)工作區(qū)。同時(shí)還要鏈接一個(gè)ws2_32.lib的庫(kù)文件。
服務(wù)器端編程的步驟:
1:加載套接字庫(kù),創(chuàng)建套接字(WSAStartup()/socket());
2:綁定套接字到一個(gè)IP地址和一個(gè)端口上(bind());
3:等待和接收數(shù)據(jù)(sendto()/recvfrom());
4:關(guān)閉套接字,關(guān)閉加載的套接字庫(kù)(closesocket()/WSACleanup())。
服務(wù)器端代碼如下:
#include
#include
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 1, 1 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
return;
}
if ( LOBYTE( wsaData.wVersion ) != 1 ||
HIBYTE( wsaData.wVersion ) != 1 )
{
WSACleanup( );
return;
}
SOCKET sockSrv=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(7003);
bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
char recvBuf;
SOCKADDR addrClient;
int len=sizeof(SOCKADDR);
recvfrom(sockSrv,recvBuf,50,0,(SOCKADDR*)&addrClient,&len);
printf(“%s\n”,recvBuf);
closesocket(sockSrv);
WSACleanup();
}
對(duì)于基于UDP的socket客戶端來(lái)說(shuō),要進(jìn)行如下步驟:
1:創(chuàng)建一個(gè)套接字(socket);
2:向服務(wù)器發(fā)送數(shù)據(jù)(sendto);
3:關(guān)閉套接字;
代碼如下:
#include
#include
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
return;
}
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 ) {
WSACleanup( );
return;
}
SOCKET sockClient=socket(AF_INET,SOCK_DGRAM,0);
SOCKADDR_IN addrClient;
addrClient.sin_addr.S_un.S_addr=inet_addr(“127.0.0.1”);
addrClient.sin_family=AF_INET;
addrClient.sin_port=htons(8889);
SOCKADDR_IN addrSrv;
sendto(sockClient,”hi”,3,0,(SOCKADDR*)&addrClient,sizeof(SOCKADDR));
}
LINUX環(huán)境下TCP/UDP編程步驟:
TCP編程步驟:
一. 服務(wù)端:
1.socket(int domain,int type,int protocol):建立套接字;
2 .bind(int sockid,struct sockaddr *addrp,socklen_t addrlen):把本機(jī)地址和端口跟上一步建立的socket綁定在一起;
3.listen(int sockid,int qsize):監(jiān)聽某套接字;
4.fd=accept(int sockid,struct sockaddr *callerid,socklen_t *addrlenp):等待某套接字接收信息;
5.recv(int fd,void *buf,size_t nbytes,int flags):從套接字接收數(shù)據(jù);
6.close(fd) 和close(sockid)
二.客戶端:
1. socket():建立套接字;
2.connect(int sockid,struct sockaddr *serv_addrp,socklen_t addrlen):連接到服務(wù)器;
3. send(int sockfd,const void *buf,size_t nbytes,int flags):發(fā)送數(shù)據(jù)到服務(wù)器.
4. close(sockid);
UDP編程步驟:
一,服務(wù)端:
1. socket():同上;
2. bind():同上;
3. recvfrom(int sockfd,void*buff,size_t nbytes,int flags,struct sockaddr*from,socklen_t*addrlen):在套接字口接收數(shù)據(jù),并且記錄下接收到的數(shù)據(jù)來(lái)源;一定要注意這里的參數(shù)addrlen,它不僅是函數(shù)的輸出,也是函數(shù)的輸入!所以要在調(diào)用該函數(shù)之前對(duì)addrlen賦值sizeof(struct sockaddr)。否則返回的地址from將會(huì)出錯(cuò)!
4. close(sockfd);
二. 客戶端:
1. socket();同上;
2. sendto(int sockfd,const void*buff,size_t nbytes,int flags,const struct sockaddr*to,socklen_t addrlen):往指定的地址發(fā)送數(shù)據(jù);
3. close(sockfd);
UDP Server程序
1、編寫UDP Server程序的步驟
(1)使用socket()來(lái)建立一個(gè)UDP socket,第二個(gè)參數(shù)為SOCK_DGRAM。
(2)初始化sockaddr_in結(jié)構(gòu)的變量,并賦值。sockaddr_in結(jié)構(gòu)定義:
struct sockaddr_in {
uint8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero;
};
這里使用“08”作為服務(wù)程序的端口,使用“INADDR_ANY”作為姿凱綁定的IP地址即任何主機(jī)上的地址。
(3)使用bind()把上面的socket和定義的IP地址和端口綁定。這里檢查bind()是否執(zhí)行成功,如果有錯(cuò)誤就退出。這樣可以防止服務(wù)程序重復(fù)運(yùn)行的問(wèn)題。
(4)進(jìn)入無(wú)限循環(huán)程序,使用recvfrom()進(jìn)入等待狀態(tài),直到接收到客戶程序發(fā)送的數(shù)據(jù),就處理收到的數(shù)據(jù),并向客戶程序發(fā)送反饋。這里是直接把收到的數(shù)據(jù)發(fā)回給客戶程序。
2、udpserv.c程序內(nèi)容:
#include
#include
#include
#include
#include
#include
#define MAXLINE 80
#define SERV_PORT 8888
void do_echo(int sockfd, struct sockaddr *pcliaddr, socklen_t clilen)
{
int n;
socklen_t len;
char mesg;
for(;;)
{
len = clilen;
/* waiting for receive data */
n = recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);
/* sent data back to client */
sendto(sockfd, mesg, n, 0, pcliaddr, len);
}
}
int main(void)
{
int sockfd;
struct sockaddr_in servaddr, cliaddr;
sockfd = socket(AF_INET, SOCK_DGRAM, 0); /* create a socket */
/* init servaddr */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
/* bind address and port to socket */
if(bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
{
perror(“bind error”);
exit(1);
}
do_echo(sockfd, (struct sockaddr *)&cliaddr, sizeof(cliaddr));
return 0;
}
UDP Client程序
1、編寫UDP Client程序的步驟
(1)初始化sockaddr_in結(jié)構(gòu)舉冊(cè)伍的變量,并賦值。這里使用“8888”作為連接的服務(wù)程序的端口,從命令行參數(shù)讀取IP地址,并且判斷IP地址是否符合要求。
(2)使用socket()來(lái)建立一個(gè)UDP socket,第二個(gè)參數(shù)為SOCK_DGRAM。
(3)使用connect()來(lái)建立與服務(wù)程序的連接。與TCP協(xié)議不同,UDP的connect()并沒有與服務(wù)程序三次握手。上面我們說(shuō)了UDP是非連接的,實(shí)際上也可以是連接的。使用連接的UDP,kernel可以直接返回錯(cuò)誤信息給用戶程序,從而避免由于沒有接收到數(shù)據(jù)而導(dǎo)致調(diào)用recvfrom()一直等待下去,看上去好像客戶程序沒有反應(yīng)一樣。
(4)向服務(wù)程序發(fā)送數(shù)據(jù),因?yàn)槭褂眠B接的UDP,所以使用write()來(lái)替代sendto()。這里的數(shù)據(jù)直接從標(biāo)準(zhǔn)輸入讀取用戶輸入。正或
(5)接收服務(wù)程序發(fā)回的數(shù)據(jù),同樣使用read()來(lái)替代recvfrom()。
(6)處理接收到的數(shù)據(jù),這里是直接輸出到標(biāo)準(zhǔn)輸出上。
2、udpclient.c程序內(nèi)容:
#include
#include
#include
#include
#include
#include
#include
#include
#define MAXLINE 80
#define SERV_PORT 8888
void do_cli(FILE *fp, int sockfd, struct sockaddr *pservaddr, socklen_t servlen)
{
int n;
char sendline, recvline;
/* connect to server */
if(connect(sockfd, (struct sockaddr *)pservaddr, servlen) == -1)
{
perror(“connect error”);
exit(1);
}
while(fgets(sendline, MAXLINE, fp) != NULL)
{
/* read a line and send to server */
write(sockfd, sendline, strlen(sendline));
/* receive data from server */
n = read(sockfd, recvline, MAXLINE);
if(n == -1)
{
perror(“read error”);
exit(1);
}
recvline = 0; /* terminate string */
fputs(recvline, stdout);
}
}
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in srvaddr;
/* check args */
if(argc != 2)
{
printf(“usage: udpclient \n”);
exit(1);
}
/* init servaddr */
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(SERV_PORT);
if(inet_pton(AF_INET, argv, &servaddr.sin_addr)
{
printf(” is not a valid IPaddress\n”, argv);
exit(1);
}
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
do_cli(stdin, sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
return 0;
}
運(yùn)行例子程序
1、編譯例子程序
使用如下命令來(lái)編譯例子程序:
gcc -Wall -o udpserv udpserv.c
gcc -Wall -o udpclient udpclient.c
編譯完成生成了udpserv和udpclient兩個(gè)可執(zhí)行程序。
2、運(yùn)行UDP Server程序
執(zhí)行./udpserv &命令來(lái)啟動(dòng)服務(wù)程序。我們可以使用netstat -ln命令來(lái)觀察服務(wù)程序綁定的IP地址和端口,部分輸出信息如下:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN
tcp.0.0.1:631 0.0.0.0:* LISTEN
udp 0 0 0.0.0.0:.0.0.0:*
udp 0 0 0.0.0.0:8888 0.0.0.0:*
udp 0 0 0.0.0.0:111 0.0.0.0:*
udp 0 0 0.0.0.0:882 0.0.0.0:*
可以看到udp處有“0.0.0.0:8888”的內(nèi)容,說(shuō)明服務(wù)程序已經(jīng)正常運(yùn)行,可以接收主機(jī)上任何IP地址且端口為8888的數(shù)據(jù)。
如果這時(shí)再執(zhí)行./udpserv &命令,就會(huì)看到如下信息:
bind error: Address already in use
說(shuō)明已經(jīng)有一個(gè)服務(wù)程序在運(yùn)行了。
3、運(yùn)行UDP Client程序
執(zhí)行./udpclient 127.0.0.1命令來(lái)啟動(dòng)客戶程序,使用127.0.0.1來(lái)連接服務(wù)程序,執(zhí)行效果如下:
Hello, World!
Hello, World!
this is a test
this is a test
^d
輸入的數(shù)據(jù)都正確從服務(wù)程序返回了,按ctrl+d可以結(jié)束輸入,退出程序。
如果服務(wù)程序沒有啟動(dòng),而執(zhí)行客戶程序,就會(huì)看到如下信息:
$ ./udpclient 127.0.0.1
test
read error: Connection refused
說(shuō)明指定的IP地址和端口沒有服務(wù)程序綁定,客戶程序就退出了。這就是使用connect()的好處,注意,這里錯(cuò)誤信息是在向服務(wù)程序發(fā)送數(shù)據(jù)后收到的,而不是在調(diào)用connect()時(shí)。如果你使用tcpdump程序來(lái)抓包,會(huì)發(fā)現(xiàn)收到的是ICMP的錯(cuò)誤信息。
香港服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過(guò)10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開發(fā)經(jīng)驗(yàn)。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊(cè)、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。
當(dāng)前文章:LinuxSocket:本地UDP通信詳解(linuxsocket本地UDP)
本文網(wǎng)址:http://fisionsoft.com.cn/article/dhhoehd.html


咨詢
建站咨詢
