此方式首先伺服器端建立乙個監聽,並阻塞至accetp處,當乙個客戶端進行連線時,accept函式並啟用並返回,此時用fork函式建立乙個子程序,由子程序執行客戶請求處理程式,而父程序繼續監聽,等待其他的客戶端。此方式會建立很多的程序,程序個數受具體的作業系統的限制。這種併發伺服器的缺點在於建立乙個子程序花費的cpu時間較多,如現在的web服務一天需要處理百萬計的連線,為每個連線建立乙個子程序就會浪費很多的cpu時間,此可以通過預先建立程序的方法來解決,此將作為單獨的乙個模組說明。
例子:回射伺服器,接受客戶端的請求,並讀取客戶的資料並原樣返回,此程式在centos 5.0中測試通過。
伺服器程式:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define serv_port 2003
#define maxline 1024
#define listenq 4
/* 根據埠號建立連線 */
int makelistenbyport(short port)
int listenfd;
struct sockaddr_in servaddr;
listenfd = socket(af_inet, sock_stream, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = af_inet;
servaddr.sin_addr.s_addr = htonl(inaddr_any);
servaddr.sin_port = htons(port);
bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
listen(listenfd, listenq);
return listenfd;
/* 客戶請求處理函式 */
void requestproductfunc(int connfd)
char buf[maxline];
int n;
for(;;) else{
write(connfd, buf, n);
int main(int argc, char **argv)
int listenfd, connfd, maxfd, sockfd;
char buf[maxline];
struct sockaddr_in cliaddr;
int i;
int clilen, adrlen;
pid_t child;
listenfd = makelistenbyport(serv_port);
adrlen = sizeof(struct sockaddr);
for(;;) {
clilen = adrlen;
if((connfd = accept(listenfd, (struct sockaddr *)&cliaddr,&clilen)) < 0){
/* 如果是被中訊號中斷則繼續*/
if(errno == eintr)
continue;
else{
printf("accepterror!");
exit(0);
/* 建立乙個執行緒並呼叫客戶請求處理函式 */
if((child = fork()) == 0) {
close(listenfd);
requestproductfunc(connfd);
exit(0);
/* 父程序關閉連線,並繼續監聽 */
close(connfd);
客戶端程式:
#include
#include
#include
#include
#include
#include
#include
#define maxline 1024
#define serv_port 2003
void cli_str(file *fp, int sockfd)
char sendline[maxline];
char recvline[maxline];
memset(recvline, 0x00, sizeof(recvline));
memset(sendline, 0x00, sizeof(sendline));
printf("cli#");
while((fgets(sendline, maxline, fp)) != null) {
write(sockfd, sendline, strlen(sendline));
if(read(sockfd, recvline, maxline) == 0) {
printf("str_cli:server terminated prematurely\n");
exit(0);
fputs(recvline, stdout);
fflush(stdout);
memset(recvline, 0x00, sizeof(recvline));
printf("cli#");
int main(int argc, char **argv)
int sockfd;
struct sockaddr_in servaddr;
if((sockfd = socket(af_inet, sock_stream, 0)) == -1) {
printf("socket error\n");
exit(0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = af_inet;
inet_pton(af_inet, argv[1], &servaddr.sin_addr);
servaddr.sin_port = htons(serv_port);
if((connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)))== -1) {
printf("connect error\n");
exit(0);
cli_str(stdin, sockfd);
exit(0);
Unix網路程式設計伺服器設計方式之四
預先建立子程序的方式比為每個客戶端建立乙個程序的方式優越的地方在於當伺服器啟動時就將子程序建立好,當乙個客戶端連線至伺服器時選擇乙個可用的子程序處理,這樣可以節省到建立子程序的消耗。有乙個弊端是需要事先確定子程序的個數,當客戶端多於子程序的個數時,基於的客戶端只能等待可用的子程序。有一種解決方法就是...
Unix網路程式設計伺服器設計方式之六
此種方式是由主線程預先建立多個工作執行緒,並且主線程不斷的監聽連線請求,當有連線請求時先獲得鎖,並將連線放入到連線陣列中,並通知空閒的工作執行緒 即阻塞在條件等待處的工作執行緒 進行請求處理,工作執行緒得到通知後先在連線陣列中拿乙個可用的連線,並將其標記為已處理,然後釋放鎖,執行請求處理函式。此方式...
UNIX網路程式設計 併發伺服器(多程序)
以下程式的源 均是unix網路程式設計上的例子程式。intro daytimetcpsrv1.c include unp.h include include apueerror.h int main int argc,char argv tcp一般採用併發伺服器。當服務乙個客戶請求可能花費較長時間時...