7.1. Blocking(阻塞)
很多函式都會 block,accept() 會 block,全部的 recv() 函式都會 block。
socket() 建立 socket descriptor 時,kernel(核心)會將它設定為 blocking。若你不想要 blocking socket,你必須呼叫 fcntl().
如果你試著讀取 non-blocking socket,而 socket 沒有資料時,函式就不會發生 block,而是傳回 -1,並將 errno 設定為 EWOULDBLOCK。
#include
<unistd.h>
#include
<fcntl.h>
sockfd
=
socket
(
PF_INET
,
SOCK_STREAM
,
0
);
fcntl
(
sockfd
,
F_SETFL
,
O_NONBLOCK
);
如果你試著讀取 non-blocking socket,而 socket 沒有資料時,函式就不會發生 block,而是傳回 -1,並將 errno 設定為 EWOULDBLOCK。
7.2. select():同步 I/O 多工
select() 授予你同時監視多個 sockets 的權力,它會告訴你哪些 sockets 已經有資料可以讀取、哪些 sockets 已經可以寫入,如果你真的想知道,還可以告訴你哪些 sockets 觸發了例外。
即使 select() 有相當好的可移植性,不過卻是最慢的監視 sockets 方法。一個比較可行的替代方案是 libevent ,將全部的系統相依要素封裝起來,用在取得 socket 的通知。
#include <sys/select.h>
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout);
FD_SET(int fd, fd_set *set);
FD_CLR(int fd, fd_set *set);
FD_ISSET(int fd, fd_set *set);
FD_ZERO(fd_set *set);
第一個參數 n 的值是最大的那個 socket descriptor 數值在加上 1。
struct timeval 可以設定 timeout 的時間, 如果timeout為0則一個一個檢查不stop
struct timeval {
int tv_sec; // 秒(second)
int tv_usec; // 微秒(microseconds)
};
p.s. 怎決定放readfds or writefds or exceptfds
??
修改socket 設定技術
- poll vs select
??
- Socket Option 設定
修改socket 設定技術
int getsockopt(int s, int level, int optname, void *optval,
socklen_t *optlen);
int setsockopt(int s, int level, int optname, const void *optval,
socklen_t optlen);
level通常為SOL_SOCKET
optname 可以有很多,細看socket man page , 如修改receive buffer , SO_REVBUF
int rcvBufferSize;
int sockOptSize = sizeof(rcvBufferSize);
// Retrieve and print the default buffer size
if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &rcvBufferSize, &sockOptSize) < 0) DieWithSystemMessage("getsockopt() failed");
printf("Initial Receive Buffer Size: %d\n", rcvBufferSize);
// Double the buffer size rcvBufferSize *= 2;
if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &rcvBufferSize, sizeof(rcvBufferSize)) < 0)
DieWithSystemMessage("setsockopt() failed");
receive buffer default=>/proc/sys/net/core/rmem_default
min size=> doubled (256)
max size=>/proc/sys/net/core/rmem_max
沒有留言:
張貼留言