tcp/ip winsock程式設計要點
ackarlix
利用
winsock
程式設計由同步和非同步方式,同步方式邏輯清晰,程式設計專注於應用,在搶先式的多工作業系統中
(winnt
、win2k)
採用多執行緒方式效率基本達到非同步方式的水平,應此以下為同步方式程式設計要點。
1、快速通訊
winsock
的nagle
演算法將降低小資料報的傳送速度,而系統預設是使用
nagle演算法,
使用 int setsockopt(
socket s,
int level,
int optname,
const char far *optval,
int optlen
);函式關閉它
例子:
socket sconnect;
sconnect=::socket(af_inet,sock_stream,ipproto_tcp);
int bnodelay = 1;
int err;
err = setsockopt(
sconnect,
ipproto_tcp,
tcp_nodelay,
(char *)&bnodelay,
sizoeof(bnodelay));//
不採用延時演算法
if (err != no_error)
trace ("setsockopt failed for some reason/n");;
2、socket
的segmentsize
和收發緩衝
tcpsegmentsize
是傳送接受時單個資料報的最大長度,系統預設為
1460
,收發緩衝大小為
8192。在
sock_stream
方式下,如果單次傳送資料超過
1460
,系統將分成多個資料報傳送,在對方接受到的將是乙個資料流,應用程式需要增加斷幀的判斷。當然可以採用修改登錄檔的方式改變
1460
的大小,但
micrcosoft
認為1460
是最佳效率的引數,不建議修改。
在工控系統中,建議關閉
nagle
演算法,每次傳送資料小於
1460
個位元組(推薦
1400
),這樣每次傳送的是乙個完整的資料報,減少對方對資料流的斷幀處理。
3、同步方式中減少斷網時
connect
函式的阻塞時間
同步方式中的斷網時
connect
的阻塞時間為
20秒左右,可採用
gethostbyaddr
事先判斷到服務主機的路徑是否是通的,或者先
ping
一下對方主機的
ip位址。
a、採用
gethostbyaddr
阻塞時間不管成功與否為
4秒左右。
例子:
long lport=3024;
struct sockaddr_in serverhostaddr;//
服務主機位址
serverhostaddr.sin_family=af_inet;
serverhostaddr.sin_port=::htons(u_short(lport));
serverhostaddr.sin_addr.s_addr=::inet_addr("192.168.1.3");
hostent* presult=gethostbyaddr((const char *) &
(serverhostaddr.sin_addr.s_addr),4,af_inet);
if(null==presult)
else
b、採用
ping
方式時間約
2秒左右暫略4
、同步方式中解決
recv
,send
阻塞問題
採用select
函式解決,在收發前先檢查讀寫可用狀態。a、讀
例子:
timeval tv01 = ;//1ms
鐘延遲,
實際為0-10
毫秒int nselectret;
int nerrorcode;
fd_set fdr = ;
nselectret=::select(0, &fdr, null, null, &tv01);//
檢查可讀狀態
if(socket_error==nselectret)
if(nselectret==0)//
超時發生,無可讀資料
else
b、寫timeval tv01 = ;//1ms
鐘延遲,
實際為9-10
毫秒int nselectret;
int nerrorcode;
fd_set fdw = ;
nselectret=::select(0, null, null,&fdw, &tv01);//
檢查可寫狀態
if(socket_error==nselectret)
if(nselectret==0)//
超時發生,緩衝滿或網路忙
else
5、改變
tcp收發緩衝區大小
系統預設為
8192
,利用如下方式可改變。
socket sconnect;
sconnect=::socket(af_inet,sock_stream,ipproto_tcp);
int nrcvbuf=1024*20;
int err=setsockopt(
sconnect,
sol_socket,
so_sndbuf,//
寫緩衝,讀緩衝為
so_rcvbuf
(char *)&nrcvbuf,
sizeof(nrcvbuf));
if (err != no_error)
在設定緩衝時,檢查是否真正設定成功用
int getsockopt(
socket s,
int level,
int optname,
char far *optval,
int far *optlen );
6、服務方同一埠多
ip位址的
bind
和listen
在可靠性要求高的應用中,要求使用雙網和多
網路通道,再服務方很容易實現,用如下方式可建立客戶對本機所有
ip位址在埠
3024
下的請求服務。
socket hserversocket_ds=invalid_socket;
struct sockaddr_in hostaddr_ds;//
伺服器主機位址
long lport=3024;
hostaddr_ds.sin_family=af_inet;
hostaddr_ds.sin_port=::htons(u_short(lport));
hostaddr_ds.sin_addr.s_addr=htonl(inaddr_any);
hserversocket_ds=::socket( af_inet, sock_stream,ipproto_tcp);
if(hserversocket_ds==invalid_socket)
if(socket_error==::bind(hserversocket_ds,(struct
sockaddr *)(&(hostaddr_ds)),sizeof(sockaddr)))
if(socket_error==::listen(hserversocket_ds,10))//10
個客戶
afxbeginthread(serverthreadproc,null,thread_priority_normal);
在客戶方要複雜一些,連線斷後,重聯不成功則應換下乙個
ip位址連線。也可採用同時連線好後備用的方式。7、用
tcp/ip winsock
實現變種
client/server
傳統的client/server
為客戶問、服務答,收發是成對出現的。而變種的
client/server
是指在連線時有客戶和服務之分,建立好通訊連線後,不再有嚴格的客戶和服務之分,任何方都可主動傳送,需要或不需要回答看應用而言,這種方式在工控行業很有用,比如
rtdb
作為i/o server
的客戶,但
i/o server
也可主動向
rtdb
傳送開關狀態變位、隨即事件等資訊。在很大程度上減少了
網路通訊負荷、提高了效率。
採用1-6
的tcp/ip
程式設計要點,在
client
和server
方均已接收優先,適當控制時序就能實現。
TCP IP Winsock程式設計要點
利用winsock程式設計由同步和非同步方式,同步方式邏輯清晰,程式設計專注於應用,在搶先式的多工作業系統中 winnt win2k 採用多執行緒方式效率基本達到非同步方式的水平,應此以下為同步方式程式設計要點。1 快速通訊 winsock的nagle演算法將降低小資料報的傳送速度,而系統預設是使用...
TCP IP Winsock程式設計要點
利用winsock程式設計由同步和非同步方式,同步方式邏輯清晰,程式設計專注於應用,在搶先式的多工作業系統中 winnt win2k 採用多執行緒方式效率基本達到非同步方式的水平,應此以下為同步方式程式設計要點。1 快速通訊 winsock的nagle演算法將降低小資料報的傳送速度,而系統預設是使用...
TCP IP Winsock程式設計要點
利用winsock程式設計由同步和非同步方式,同步方式邏輯清晰,程式設計專注於應用,在搶先式的多工作業系統中 winnt win2k 採用多執行緒方式效率基本達到非同步方式的水平,應此以下為同步方式程式設計要點。1 快速通訊 winsock的nagle演算法將降低小資料報的傳送速度,而系統預設是使用...