根據預定義程序數建立程序池。
父子程序通訊使用的ipc方式為:unix域套接字
父程序listen,aeecpt,並將連線套接字傳送到子程序,交由子程序處理該連線。
子程序處理完畢,與父程序通訊,實現資源**,並在下一連線到來交由該完畢的子程序。
#include "unp.h"
#include #define idle 0
#define busy 1
#define end 2
typedef struct pro process;
process *mypid; /*程序池*/
ssize_t write__the_fd(int fd, void *ptr, size_t nbytes, int sendfd);
pid_t make_child( int i, int listenfd );
ssize_t read_the_fd(int fd, void *ptr, size_t nbytes, int *recvfd);
void child_func( void);
void clr(int signo);
int main( int argc, char **argv )
nchild = atoi(argv[1]);
mypid = (struct pro *)malloc( nchild * sizeof( struct pro) );
bzero( &addr, sizeof(addr));
addr.sin_family = af_inet;
addr.sin_port = htons(serv_port);
addr.sin_addr.s_addr = htonl(inaddr_any);
bind(listenfd, (sa *)&addr, sizeof(struct sockaddr));
fdmax = listenfd; /*用於select */
for( i = 0; i < nchild; i++ ) /*傳入listenfd子程序關閉監聽套接字*/
int idle = nchild; /*當前空閒的子程序*/
len = sizeof(struct sockaddr);
fd_zero(&oset);
fd_zero(&rset);
listen(listenfd,5);
fd_set(listenfd, &oset);
for( ; ;)
}/* */
assert(i < nchild);
/* */
//connfd = accept(listenfd, (sa *)&clientaddr, &len);
printf("the id is %d \n",i);
mypid[i].flags = busy; /*改變子程序狀態*/
mypid[i].cnt ++; /*子程序服務次數*/
fd_set(mypid[i].fd, &oset); /*加入描述集,等待子程序*/
fdmax = max(fdmax ,mypid[i].fd);
idle --; /*空閒程序減少*/
/*通知子程序*/
write_the_fd(mypid[i].fd, " ", 1,connfd);/*把連線套接字傳送給子程序*/
close(connfd); /*因為有有乙個confd在飛,所以這個可以關閉*/
if(--nselect ==0)
continue;
} else
if(--nselect == 0)
break;
}}
}}void clr(int signo)
sleep(2);
kill(getpid(), sigterm);
return;
}pid_t make_child( int i, int listenfd )
if( child > 0 )
/*子程序*/
close( fd[0] );
close(listenfd);
dup2( fd[1], stderr_fileno);
close( fd[1]);
child_func();
}void child_func( void)
if((n < 0)&&( errno == eintr))
goto again;
else if(n < 0)
err_sys("error");
else if(n ==0) }}
ssize_t write_the_fd(int fd, void *ptr, size_t nbytes, int sendfd) control_un;
struct cmsghdr *cmptr;
msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control);
cmptr = cmsg_firsthdr(&msg);
cmptr->cmsg_len = cmsg_len(sizeof(int));
cmptr->cmsg_level = sol_socket;
cmptr->cmsg_type = scm_rights;
*((int *) cmsg_data(cmptr)) = sendfd;
msg.msg_name = null;
msg.msg_namelen = 0;
iov[0].iov_base = ptr;
iov[0].iov_len = nbytes;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
return(sendmsg(fd, &msg, 0));
}ssize_t read_the_fd(int fd, void *ptr, size_t nbytes, int *recvfd) control_un;
struct cmsghdr *cmptr;
msg.msg_control = control_un.control;
msg.msg_controllen = sizeof(control_un.control);
msg.msg_name = null;
msg.msg_namelen = 0;
iov[0].iov_base = ptr;
iov[0].iov_len = nbytes;
msg.msg_iov = iov;
msg.msg_iovlen = 1;
if ( (n = recvmsg(fd, &msg, 0)) <= 0)
return(n);
if ( (cmptr = cmsg_firsthdr(&msg)) != null &&
cmptr->cmsg_len == cmsg_len(sizeof(int))) else
*recvfd = -1;
return(n);
}
簡單實現TCP服務端與客戶端
1 include2 include3 include4 include5 include6 include7 include8 include9 10 tcp服務端 簡單的網路聊天程式 11 1 建立socket 12 2 為socket繫結位址埠 13 3 開始監聽socket 告訴作業系統,開...
TCP客戶 伺服器簡單Socket程式
建立乙個 tcp 連線時會發生下述情形 1.伺服器必須準備好接受外來的連線。這通常通過呼叫 socket bind 和 listen 這三個函式來完成,我們稱之為被動開啟。2.客戶通過呼叫 connect 發起主動開啟,這導致客戶tcp傳送乙個syn 同步 分節,標識希望連線的伺服器端口以及初始序號...
簡單TCP客戶 伺服器的理解
1.伺服器部分 socket bind listen之後,for迴圈內accept獲取 已連線套接字 描述符 fork子程式處理該連線的資料傳輸。2.客戶端部分 socket connect之後,呼叫資料傳送函式向該套接字內寫資料,即傳送資料。1.程序exit後,會關閉所有開啟的檔案描述符,包括套接...