非阻塞讀和寫版 TCP回顯C S

2021-08-15 20:50:11 字數 3671 閱讀 7546

通過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 呼叫。阻塞呼叫很像乙個檔案的讀寫。當你讀資料或者寫資料時,直 到操作完成,函式才會返回。不同的是...