通過fcntl設定套接字,標準輸出,標準輸入為非阻塞
客戶端**:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define bufsize 4096
int max(int a,int b)
char* gf_time(void)
ptr = ctime(&tv.tv_sec);
strcpy(str,&ptr[11]);
snprintf(str + 8,sizeof(str) - 8,".%06ld",tv.tv_usec);
return str;
}void client_noblock_echo(int fd)
val = fcntl(stdin_fileno,f_getfl,0);
if (fcntl(stdin_fileno,f_setfl,val | o_nonblock) < 0)
val = fcntl(stdout_fileno,f_getfl,0);
if (fcntl(stdout_fileno,f_setfl,val | o_nonblock) < 0)
char to[bufsize],from[bufsize];
char *tws,*twr; // 傳送緩衝區準備傳送的(wait
send) 準備接收的資料(wait receive from stdin)
char *fwo,*fwr; //接收緩衝區準備輸出的(wait output to stdout) 準備接收的資料(receive from server)
fd_set rs,ws;
tws = twr = to;
fwo = fwr = from;
int ioeof = 0;
int maxfdp1 = max(fd,max(stdout_fileno,stdin_fileno)) + 1;
int n,nw;
for (; ;)
if (fwo != fwr)
if (tws != twr)
if (fwr < &from[bufsize])
if (select(maxfdp1,&rs,&ws,null,null) < 0)
if (fd_isset(stdin_fileno,&rs))
}else
if (n == 0)
}}else
}if (fd_isset(fd,&rs))
}else
if (n == 0) else
}else
}if (fd_isset(stdout_fileno,&ws) && ((n = fwr - fwo) > 0))
}else }}
if (fd_isset(fd,&ws) && ((n = twr - tws) > 0))
}else }}
}}}}int main(int argc,char** argv)
struct addrinfo hints;
hints.ai_flags = ai_all;
hints.ai_family = af_unspec;
hints.ai_socktype = sock_stream;
hints.ai_protocol = ipproto_tcp;
struct addrinfo* results;
int err;
if ((err = getaddrinfo(argv[1],argv[2],&hints,&results)) != 0)
struct addrinfo* dummy = results;
int sockfd;
for (; dummy != null; dummy = dummy->ai_next)
if (connect(sockfd,dummy->ai_addr,dummy->ai_addrlen) == 0)
close(sockfd);
}if (dummy == null)
freeaddrinfo(results);
client_noblock_echo(sockfd);
return
0;}
服務端**:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define listenq 100
#define bufsize 4096
void server_echo(int fd)
}}void sig_child(int signo)
}int main(int argc,char** argv)
struct addrinfo hints;
bzero(&hints,sizeof(struct addrinfo));
hints.ai_flags = ai_passive;
hints.ai_family = af_unspec;
hints.ai_socktype = sock_stream;
hints.ai_protocol = ipproto_tcp;
struct addrinfo* results;
int err;
if ((err = getaddrinfo(null,argv[1],&hints,&results)) != 0)
struct addrinfo* dummy = results;
int sockfd;
for (; dummy != null; dummy = dummy->ai_next)
if (bind(sockfd,dummy->ai_addr,dummy->ai_addrlen) == 0)
close(sockfd);
}if (dummy == null)
freeaddrinfo(results);
if (listen(sockfd,listenq) < 0)
if (signal(sigchld,sig_child) == sig_err)
int connfd;
int ppid;
for (; ;)
printf("accept error: %s\n",strerror(errno));
exit(1);
}if ((ppid = fork()) < 0) else
if (ppid == 0)
close(connfd);}}
測試:
啟動伺服器->啟動tcpdump捕捉(本次測試伺服器是在主機上.所以需要通過網絡卡lo捕捉,不然是抓不到的)->啟動客戶端,如圖:
阻塞 非阻塞 讀終端
阻塞和非阻塞是檔案的屬性還是read函式的屬性?答 檔案的屬性 預設情況下,檔案的屬性是阻塞還是非阻塞的?預設不阻塞 普通檔案 預設阻塞 終端裝置 de tty,管道,套接字 errno與eagain errno eagain表示緩衝區無資料可讀 即 此時並沒有read讀到資料 阻塞讀終端 int ...
Linux 阻塞 非阻塞讀終端
阻塞讀終端 block指當串列埠輸入緩衝區沒有資料的時候,read函式將會阻塞在這裡,移植到串列埠輸入緩衝區中有資料可讀取,read讀到了需要的位元組數之後,返回值為讀到的位元組數 include include int main void write stdout fileno,buf,n ret...
阻塞和非阻塞
在 windows 下的 socket 程式設計有兩個程式設計模型,阻塞和非阻塞。有時,他們也被叫做同步 阻 塞 和非同步 非阻塞 在 unix 中只支援阻塞模型。阻塞 indy 使用阻塞 socket 呼叫。阻塞呼叫很像乙個檔案的讀寫。當你讀資料或者寫資料時,直 到操作完成,函式才會返回。不同的是...