recvfrom函數(shù)如何使用 udp應(yīng)用服務(wù)器程序有哪些?
udp應(yīng)用服務(wù)器程序有哪些?#includeltstdio.hgt#includeltstring.hgt#includeltunistd.hgt#includeltsys/types.hgt#inc
udp應(yīng)用服務(wù)器程序有哪些?
#includeltstdio.hgt
#includeltstring.hgt
#includeltunistd.hgt
#includeltsys/types.hgt
#includeltsys/socket.hgt
#includeltstdlib.hgt
#includeltnetinet/in.hgt
#includeltarpa/inet.hgt
#definePORT1234
#defineMAXDATASIZE100
intdefault(typedef)
{
intsockfd
structsockaddr_inserver
structsockaddr_inclient
socklen_tlen
int num
charbuf[MAXDATASIZE]
if((sockfdsocket(AF_INET,SOCK_DGRAM,0))-1)
{
perror(#34Creatingsocketfailed.
#34)
exit(1)
}
bzero(ampserver,sizeof(server))
_familyAF_INET
_porthtons(PORT)
_addr.s_addrhtonl(INADDR_ANY)
if(bind(sockfd,(structsockaddr*)ampserver,sizeof(server))-1)
{
perror(#34Bind()error.
#34)
exit(1)
}
lensizeof(client)
while(1)
{
numrecvfrom(sockfd,buf,MAXDATASIZE,0,(structsockaddr*)ampclient,amplen)
if(numlt0)
{
perror(#34recvfrom()error.
#34)
exit(1)
}
buf[num]#390#39
printf(#34Yougotamessagelt%sgtfromclient.
It#39sipis%s,portis%d.
#34,buf,inet_ntoa(_addr),htons(_port))
sendto(sockfd,#34Welcome
#34,8,0,(structsockaddr*)ampclient,len)
if(!strcmp(buf,#34bye#34)){
break
}
}
close(sockfd)
}#includeltstdio.hgt
#includeltstdlib.hgt
#includeltunistd.hgt
#includeltstring.hgt
#includeltsys/types.hgt
#includeltsys/socket.hgt
#includeltnetinet/in.hgt
#includeltnetdb.hgt
#includeltarpa/inet.hgt
#definePORT1234
#defineMAXDATASIZE100
intmain(tchar,char*argv[])
{
intsockfd,num
charbuf[MAXDATASIZE]
structhostent*he
structsockaddr_inserver,peer
if(argc!3)
{
printf(#34Usage:%sltIPaddressgtltmessagegt
#34,argv[0])
exit(1)
}
if((sockfdsocket(AF_INET,SOCK_DGRAM,0))-1)
{
printf(#34socket()error
#34)
exit(1)
}
bzero(ampserver,sizeof(server))
_familyAF_INET
_porthtons(PORT)
_addr.s_addrinet_addr(argv
udp應(yīng)用服務(wù)器程序有哪些?
)_addr.s_addrinet_addr(argv
udp應(yīng)用服務(wù)器程序有哪些?
)if(connect(sockfd,(structsockaddr*)ampserver,sizeof(server))-1)
{
printf(#34connect()error.
#34)
exit(1)
}
send(sockfd,argv
如何解決socket阻塞?
,strlen(argv如何解決socket阻塞?
),0)while(1)
{
if((numrecv(sockfd,buf,MAXDATASIZE,0))-1)
{
printf(#34recv()error.
#34)
exit(1)
}
buf[num]#390#39
printf(#34ServerMessage:%s.
#34,buf)
break
}
count(sockfd)
}
如何解決socket阻塞?
的原因socket是以數(shù)據(jù)流的形式正在發(fā)送數(shù)據(jù),收不到方到底對(duì)方每個(gè)月發(fā)送中了多少數(shù)據(jù),也能只要對(duì)方一年發(fā)送中的數(shù)據(jù)能在同一刻收得到到,因?yàn)镽eceive方法是這樣工作的:
接受一個(gè)byye[]類(lèi)型的參數(shù)以及緩沖區(qū),在當(dāng)經(jīng)過(guò)一定會(huì)的時(shí)間后把收不到到的數(shù)據(jù)填充到這個(gè)緩沖區(qū)里面,而且前往不好算可以接收到數(shù)據(jù)的長(zhǎng)度,這個(gè)實(shí)際能接收到的數(shù)據(jù)長(zhǎng)度有可能為0(是沒(méi)有接收到數(shù)據(jù))、大于10小于等于緩沖區(qū)的長(zhǎng)度(收不到到數(shù)據(jù),可是沒(méi)有我們預(yù)期的多)、不等于緩沖區(qū)的長(zhǎng)度(那說(shuō)明接收到的數(shù)據(jù)小于等于我們市場(chǎng)的預(yù)期的長(zhǎng)度)。
你每次收不到緩沖區(qū)都用互成int32[]byteMessage,另外你沒(méi)有檢查收得到到的數(shù)據(jù)長(zhǎng)度,所以我第一次你收得到到的數(shù)據(jù)是123456,一次你只接收到了8,不過(guò)緩沖區(qū)里面有23456,因此加下來(lái)就是823456了。
socket接收緩沖區(qū)的大小有講究,設(shè)置里大了能接收站了起來(lái)慢,只不過(guò)它要等盡可能好的數(shù)據(jù)收得到到了再前往;設(shè)置中小了必須亂詞過(guò)調(diào)用收不到方法才能把數(shù)據(jù)可以接收完,socket有個(gè)屬性,標(biāo)注了系統(tǒng)設(shè)置為的能接收緩沖區(qū)大小,也可以可以參考這個(gè)!
還有就是用recv讀取文件,可是因此還不知道緩存里有多少數(shù)據(jù),假如是阻塞住模式,到最后必然等到已超時(shí)才知道數(shù)據(jù)巳經(jīng)讀取文件后,這是個(gè)問(wèn)題。
那個(gè)是用fgetc,按照前往判斷是否是是feof:
whlie(1){afgetc(f);if(feof(f))break;//…
bfgetc(f);if(feof(f))break;//…}不過(guò),我還不知道讀取之后后第三次動(dòng)態(tài)鏈接庫(kù)fgetc會(huì)不會(huì)堵塞,不需要測(cè)試3。
在非阻塞住模式下,我們用recv就可以不很快搞定了,但是造成堵塞模式下,而我們不知道緩沖區(qū)有多少數(shù)據(jù),不能再內(nèi)部函數(shù)recv試圖清理。
在用一個(gè)小小的技巧,利用columns函數(shù),我們可以不很快幫你搞定這個(gè)問(wèn)題:
select函數(shù)主要是用于監(jiān)視一個(gè)文件描述符集合,如果不是集合中的描述符沒(méi)有變化,則一直都阻塞在這里,直到此時(shí)連接失敗時(shí)間經(jīng)過(guò);在超時(shí)時(shí)間內(nèi),一但某個(gè)描述符不觸發(fā)了你所如此關(guān)心的事件,select立即直接返回,檢索數(shù)據(jù)庫(kù)文件描述符子集一次性處理相應(yīng)事件;tablename函數(shù)程序出錯(cuò)則直接返回大于0零的值,如果不是有事件觸發(fā)時(shí),則回可以觸發(fā)事件的描述符個(gè)數(shù);假如超時(shí),直接返回0,即沒(méi)有數(shù)據(jù)可讀。
重點(diǎn)只在于:我們這個(gè)可以用select的已超時(shí)特性,將連接失敗時(shí)間系統(tǒng)設(shè)置為0,通過(guò)檢測(cè)select的返回值,就這個(gè)可以推測(cè)緩沖是否是被全部刪除。通過(guò)這個(gè)技巧,使一個(gè)阻塞的socket成了‘非阻塞'socket.
現(xiàn)在就是可以得出解決方案了:不使用tablename函數(shù)來(lái)監(jiān)視要?jiǎng)h掉的socket描述符,并把超時(shí)時(shí)間可以設(shè)置為0,有時(shí)候讀取文件一個(gè)字節(jié)然后再扔掉(或則通過(guò)業(yè)務(wù)必須參與處理,隨你便了),若是createtable趕往0,那說(shuō)明緩沖區(qū)沒(méi)數(shù)據(jù)了(“網(wǎng)絡(luò)錯(cuò)誤”了)。
structtimevaltmOut;_sec0;_usec0;fd_setfds;FD_ZEROS(ampfds);FD_SET(skt,ampfds);
intnRet;
chartmp
如何解決socket阻塞?
;memset(tmp,0,sizeof(tmp));
while(1)
{nRetselect(FD_SETSIZE,ampfds,NULL,NULL,amptmOut);if(nRet0)break;recv(skt,tmp,1,0);}
這種的好處是,不再是需要用recv、recvfrom等阻塞函數(shù)就去讀取數(shù)據(jù),只是可以使用select,借用其超時(shí)特性檢測(cè)緩沖區(qū)如何確定為空來(lái)推測(cè)是否需要有數(shù)據(jù),有數(shù)據(jù)時(shí)才動(dòng)態(tài)創(chuàng)建recv參與徹底清除。
都說(shuō)同時(shí)可以不用recv和socket的連接失敗設(shè)置去刪掉啊,這個(gè)是啊,不過(guò)你不需要然后對(duì)socket描述符設(shè)置中已超時(shí)時(shí)間,而是為全部刪除數(shù)據(jù)而直接直接修改socket描述符的屬性,可能會(huì)會(huì)影響大到其他地方的使用,照成系統(tǒng)比較奇葩的問(wèn)題,因?yàn)?,不我推薦建議使用。