#include
#include
#include
#include
#include
#include
#include
int main()
{
char buf[1024]={0};
pid_t pid;
int ret=0;
int fd = open("./temp.txt", O_CREAT|O_TRUNC|O_RDWR, 0666);
if( fd == -1 ){
perror("open ./temp.txt");
return -1;
}
if ((pid = fork()) < 0) {
perror("fork");
return -1;
}
else if (pid == 0) { //child process
sleep(1);
ret = sprintf(buf, "child process pid:%d,parent pid:%d\n", getpid(), getppid());
write(fd, buf, ret);
close(fd);
exit(0);
}
else { //parent process
ret = sprintf(buf, "parent process pid:%d, child pid:%d\n", getpid(), pid);
write(fd, buf, ret);
close(fd);
}
waitpid(pid, NULL, 0);
return 0;
}
运行结果如下:
[root@lghvm001 multi_process]# gcc inherit_fd.cchild process pid:18029,parent pid:18028
结论:子进程继承了父进程已经打开了的文件描述符。
/* tcp_server.c */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MAXLINE 1024
#define BACKLOG 50
int main(int argc, char** argv)
{
int listenfd, connfd, n = 0;
struct sockaddr_in servaddr, cliaddr;
pid_t pid;
socklen_t clilen;
signal(SIGCHLD, SIG_IGN); //避免子进程成为僵尸进程
if( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){
printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
return -1;
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET; //IPv4
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); //自动填入本机的IP地址
/*
if( inet_pton(AF_INET, "172.23.1.180", &servaddr.sin_addr) <= 0){ // [将“点分十进制”ip-> 网络字节序“整数”ip]
printf("inet_pton error for %s\n","172.23.1.180");
return -1;
}
*/
servaddr.sin_port = htons(6666); //将端口号转换为网络字节序
if( bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){
printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno);
return -1;
}
if( listen(listenfd, BACKLOG) == -1){
printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
return -1;
}
printf("======waiting for client's connect requestion======\n");
while(1){
if( (connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &clilen)) == -1){
printf("accept socket error: %s(errno: %d)", strerror(errno),errno);
continue;
}
if ((pid = fork()) < 0) {
perror("fork");
return -1;
}
else if (pid == 0) { //child process
char buff[MAXLINE];
close(listenfd);
fprintf(stdout, "Connected, client addr: %s\n", inet_ntoa(cliaddr.sin_addr));
if((n = recv(connfd, buff, MAXLINE-1, 0)) < 0) {
printf("Failed to receive bytes from client\n");
return -1;
}
buff[n] = '\0';
fputs("recv msg from client: ", stdout);
fputs(buff, stdout);
while (n > 0) {
if (send(connfd, buff, n, 0) != n) {
printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
return -1;
}
if((n = recv(connfd, buff, MAXLINE-1, 0)) < 0) {
printf("Failed to receive bytes from client\n");
return -1;
}
buff[n] = '\0';
fputs(buff, stdout);
}
close(connfd);
exit(0);
}
else { //parent process
close(connfd);
continue;
}
}
return 0;
}
/* tcp_client.c */
#include
#include
#include
#include
#include
#include
#include
#define MAXLINE 1024
int main(int argc, char** argv)
{ int sockfd, n, received;
int len, bytes;
char recvline[MAXLINE], sendline[MAXLINE];
struct sockaddr_in servaddr;
/*if( argc != 2){
printf("usage: ./client \n");
exit(0);
}*/
memset(recvline, 0, MAXLINE);
memset(sendline, 0, MAXLINE);
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);
return -1;
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(6666);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
/*
if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){
printf("inet_pton error for %s\n",argv[1]);
return -1;
}*/
if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){
printf("connect error: %s(errno: %d)\n", strerror(errno),errno);
return -1;
}
printf("send msg to server: \n");
while(1) {
fgets(sendline, MAXLINE, stdin);
len = strlen(sendline);
if( send(sockfd, sendline, len, 0) != len) {
printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
return -1;
}
fputs("echo from server:\n", stdout);
received = 0;
while(received < len) {
bytes = 0;
if ((bytes = recv(sockfd, recvline, MAXLINE-1, 0)) == -1 ){
perror("recv");
return -1;
}
else if(bytes == 0) {
printf("recv fail:the server has closed the connection prematually!\n");
return -1;
}
received += bytes;
recvline[bytes] = '\0';
fputs(recvline, stdout);
}
fputs("\n", stdout);
}
close(sockfd);
return 0;
}
[root@lghvm001 multi_process]# gcc tcp_server.c -o tcp_server
[root@lghvm001 multi_process]# ./tcp_server
======waiting for client's connect requestion======
Connected, client addr: 255.127.0.0
recv msg from client: hi,this is client1.
Connected, client addr: 127.0.0.1
recv msg from client: hi, this is client2.
[root@lghvm001 multi_process]# gcc tcp_client.c -o tcp_client
[root@lghvm001 multi_process]# ./tcp_client
send msg to server:
hi,this is client1.
echo from server:
hi,this is client1.
[lgh@lghvm001 multi_process]$ ./tcp_client
send msg to server:
hi, this is client2.
echo from server:
hi, this is client2.
[lgh@lghvm001 Desktop]$ ps -ef | grep tcp_server
root 18302 43605 0 14:08 pts/14 00:00:00 ./tcp_server
root 18309 18302 0 14:09 pts/14 00:00:00 ./tcp_server
root 18311 18302 0 14:09 pts/14 00:00:00 ./tcp_server
lgh 18313 18132 0 14:09 pts/22 00:00:00 grep tcp_server
[lgh@lghvm001 Desktop]$