面向連線的服務sock_stream、sock_seqpacket,在開始交換資料之前,需要在請求服務的程序套接字和提供服務的程序套接字之間建立乙個連線:客戶端通過呼叫connect.
int connect(int sockfd const struct *addr, socklen_t len);
在connect中所指定的位址是想與之通訊的伺服器位址,如果sockfd沒有繫結到乙個位址,connect會給呼叫者繫結乙個預設位址。
int connect_retry(int sockfd, const struct sockaddr *addr, socklen_t alen, int n) /* n是嘗試的時間*/
if (type == sock_stream || type == sock_seqpacket)
}return(fd);
errout:
close(fd);
errno = err;
return(-1);
}
先呼叫socket初始化套接字,然後給伺服器程序套接字繫結乙個眾所周知的位址,如果是物件導向的連線則呼叫listen宣告可以接受connect請求。
建立連線之後,就是資料傳送:
send,recv用於已經連線的套接字之間的通訊。
sendto,recvfrom可以在無連線的套接字上指定乙個位址。對於無連線的套接字,不能使用send,除非呼叫connect預先設定了目標位址。
sendmsg,recvmsg是更多選項的接受和傳輸。
apue上面向連線的服務端和客戶端的例子:
服務端:
#ifndef host_name_max#define host_name_max 256
#endif
extern int initserver(int, const struct sockaddr*, socklen_t, int);
extern void daemonize(const char *cmd);
void serve(int sockfd)
if((fp = popen("/usr/bin/uptime", "r")) == null)
else
close(clfd); }}
int main()
if(gethostname(host, n) < 0)
daemonize("ruptimed");
hint.ai_flags = ai_passive;
hint.ai_family = 0;
hint.ai_socktype = sock_stream;
hint.ai_protocol = 0;
hint.ai_addrlen = 0;
hint.ai_addr = 0;
hint.ai_canonname = 0;
hint.ai_next = null;
if((err = getaddrinfo(host, "ruptimed", &hint, &ailist)) != 0)
for(aip = ailist; aip != null; aip = aip->ai_next) }
exit(1);
}
客戶端:
void print_uptime(int sockfd)
if(n < 0) }
int main(int argc, char *argv)
hint.ai_flags = 0;
hint.ai_family = 0;
hint.ai_socktype = sock_stream;
hint.ai_protocol = 0;
hint.ai_addrlen = 0;
hint.ai_addr = null;
hint.ai_canonname = null;
hint.ai_next = null;
if((err =getaddrinfo(argv[1],"ruptimed", &hint, &ailist)) != 0)
for(aip = ailist; aip != null; aip = aip->ai_next)
if(connect_retry(sockfd, aip->ai_addr, aip->ai_addrlen, 1) < 0)
err = errno;
else
}fprintf(stderr, "can't connect to %s: %s\n", argv[1], strerror(err));
exit(1);
}
無連線的服務端服務函式:
serve(int sockfd)
if ((fp = popen("/usr/bin/uptime", "r")) == null) else
}}
客戶端傳送和接受請求的函式:
print_uptime(int sockfd, struct addrinfo *aip)
alarm(0);
write(stdout_fileno, buf, n);
}
這幾個例子都是通過getaddrinfo過獲得套接字位址資訊。
面向連線的請求在連線到來時,伺服器就一判斷所提供的服務、對於基於資料報的協議,因為沒有連線,需要先傳送個伺服器乙個資料,用來請求服務。
基於資料報的通訊客戶端的recvfrom會阻塞的等待伺服器的資料,如果伺服器沒有開啟,就會無限制等待,所以需要乙個定時器來避免呼叫recvfrom無限制阻塞。
linux socket網路程式設計之socket屬性
1.函式用法 include include int getsockopt int sockfd,int level,int optname,void optval,socklen t optlen 函式用於獲得某個套接字的屬性 int setsockopt int sockfd,int level...
網路程式設計 Python網路程式設計詳解socket
1 伺服器就是一系列硬體或軟體,為乙個或多個客戶端 服務的使用者 提供所需的 服務 它存在唯一目的就是等待客戶端的請求,並響應它們 提供服務 然後等待更多請求。2 客戶端 伺服器架構既可以應用於計算機硬體,也可以應用於計算機軟體。3 在伺服器響應客戶端之前,首先會建立乙個通訊節點,它能夠使伺服器監聽...
LiteORM學習七 遠端物件訪問Socket篇
一 摘要 在上篇我們已經講了遠端訪問物件,現在我們來看看他的內部是怎麼實現的,本次遠端物件訪問用socket實現。二 本文大綱a 摘要。b 本文大綱。c 回顧。d socket設計。e 其他。三 回顧1 在上篇liteorm學習六 遠端物件中我們說到在實體類上加入dataentity就可以在網路中訪...