《TCP/IP网络编程》阅读笔记--进程间通信

这篇具有很好参考价值的文章主要介绍了《TCP/IP网络编程》阅读笔记--进程间通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1--进程间通信

2--pipe()函数

3--代码实例

3-1--pipe1.c

3-2--pipe2.c

3-3--pipe3.c

3-4--保存信息的回声服务器端


1--进程间通信

        为了实现进程间通信,使得两个不同的进程间可以交换数据,操作系统必须提供两个进程可以同时访问的内存空间;

        为了完成进程间通信,需要创建管道(pipe);管道并非属于进程的资源,而是属于操作系统;

2--pipe()函数

#include <unistd.h>
int pipe(int filedes[2]);
// 成功时返回0,失败时返回-1
// filedes[0] 通过管道接收数据时使用的文件描述符,即管道出口
// filedes[1] 通过管道传输数据时使用的文件描述符,即管道入口

3--代码实例

3-1--pipe1.c

        子进程从管道入口写数据,父进程从管道出口读数据;

// gcc pipe1.c -o pipe
// ./pipe

#include <stdio.h>
#include <unistd.h>
#define BUF_SIZE 30

int main(int argc, char *argv[]){
    int fds[2];
    char str[] = "Who are you?";
    char buf[BUF_SIZE];
    __pid_t pid;

    pipe(fds); // 创建管道
    pid = fork();
    if(pid == 0){ // 子进程执行区域
        write(fds[1], str, sizeof(str)); // 向管道入口写数据
    }
    else{ // 父进程执行区域
        read(fds[0], buf, BUF_SIZE); // 向管道出口读数据
        puts(buf);
    }
    return 0;
}

《TCP/IP网络编程》阅读笔记--进程间通信,网络编程笔记,tcp/ip

3-2--pipe2.c

        利用一个管道实现父进程与子进程的双向通信;

// gcc pipe2.c -o pipe2
// ./pipe2

#include <stdio.h>
#include <unistd.h>
#define BUF_SIZE 30

int main(int argc, char *argv[]){
    int fds[2];
    char str1[] = "Who are you?";
    char str2[] = "Thank you for your message";
    char buf[BUF_SIZE];
    __pid_t pid;

    pipe(fds); // 创建管道
    pid = fork();
    if(pid == 0){ // 子进程执行区域
        write(fds[1], str1, sizeof(str1)); 
        sleep(2); // sleep的作用是防止子线程写的数据被子线程自身读取了,导致父进程一直等待
        read(fds[0], buf, BUF_SIZE);
        printf("Child proc output: %s \n", buf);
    }
    else{ // 父进程执行区域
        read(fds[0], buf, BUF_SIZE); 
        printf("Parent proc output: %s \n", buf);
        write(fds[1], str2, sizeof(str2));
        sleep(3);
    }
    return 0;
}

《TCP/IP网络编程》阅读笔记--进程间通信,网络编程笔记,tcp/ip

3-3--pipe3.c

        利用两个管道实现父进程与子进程的双向通信,其中收发数据在不同的管道上进行;

// gcc pipe3.c -o pipe3
// ./pipe3

#include <stdio.h>
#include <unistd.h>
#define BUF_SIZE 30

int main(int argc, char *argv[]){
    int fds1[2], fds2[2];
    char str1[] = "Who are you?";
    char str2[] = "Thank you for your message";
    char buf[BUF_SIZE];
    __pid_t pid;

    pipe(fds1), pipe(fds2); // 创建管道
    pid = fork();
    if(pid == 0){ // 子进程执行区域
        write(fds1[1], str1, sizeof(str1)); // 通过管道1写数据
        read(fds2[0], buf, BUF_SIZE); // 通过管道2读数据
        printf("Child proc output: %s \n", buf);
    }
    else{ // 父进程执行区域
        read(fds1[0], buf, BUF_SIZE); // 通过管道1读数据
        printf("Parent proc output: %s \n", buf);
        write(fds2[1], str2, sizeof(str2)); // 通过管道2写数据
        sleep(3);
    }
    return 0;
}

《TCP/IP网络编程》阅读笔记--进程间通信,网络编程笔记,tcp/ip

3-4--保存信息的回声服务器端

        服务器端创建两个进程,一个进程负责与客户端进行通信,将客户端发来的数据通过管道入口写到管道中;另一个进程负责从管道出口中读取数据,并把读取的数据保存在文件中;

        具体可运行代码参考:Chapter11

// gcc echo_storeserv.c -o echo_storeserv
// ./echo_storeserv 9190

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define BUF_SIZE 30

void error_handling(char *message){
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

void read_childproc(int sig){
    __pid_t pid;
    int status;
    pid = waitpid(-1, &status, WNOHANG);
    printf("remove proc id: %d \n", pid);
}

int main(int argc, char* argv[]){
    int serv_sock, clnt_sock;
    struct sockaddr_in serv_adr, clnt_adr;
    int fds[2];

    __pid_t pid;
    struct sigaction act; // 信号
    socklen_t adr_sz;
    int str_len, state;
    char buf[BUF_SIZE];
    if(argc != 2){
        printf("Usage : %s <port>\n", argv[0]);
        exit(1);
    }

    act.sa_handler = read_childproc; //设置信号处理函数
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    state = sigaction(SIGCHLD, &act, 0);

    serv_sock = socket(PF_INET, SOCK_STREAM, 0); // 创建 tcp socket
    memset(&serv_adr, 0, sizeof(serv_adr));
    serv_adr.sin_family = AF_INET;
    serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_adr.sin_port = htons(atoi(argv[1]));

    if(bind(serv_sock, (struct sockaddr*) &serv_adr, sizeof(serv_adr)) == -1){
        error_handling("bind() error"); 
    } 
    if(listen(serv_sock, 5) == -1){
        error_handling("listen() error");
    }

    pipe(fds);
    pid = fork();
    if(pid == 0){ // 子进程执行区域
        FILE* fp = fopen("echomsg.txt", "wt");
        char msgbuf[BUF_SIZE];
        int i, len;

        for(i = 0; i < 10; i++){
            len = read(fds[0], msgbuf, BUF_SIZE);
            fwrite((void*)msgbuf, 1, len, fp);
        }
        fclose(fp);
        return 0;
    }
    while(1){
        adr_sz = sizeof(clnt_adr);
        clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_adr, &adr_sz);
        if(clnt_sock == -1){
            continue;
        }
        else{
            puts("new client connected...");
        }

        pid = fork();
        if(pid == 0){
            close(serv_sock);
            while((str_len = read(clnt_sock, buf, BUF_SIZE)) != 0){
                write(clnt_sock, buf, str_len);
                write(fds[1], buf, str_len);
            }
            close(clnt_sock);
            puts("client disconnected...");
            return 0;
        }
        else{
            close(clnt_sock);
        }
    }
    close(serv_sock);
    return 0;

}

《TCP/IP网络编程》阅读笔记--进程间通信,网络编程笔记,tcp/ip文章来源地址https://www.toymoban.com/news/detail-703816.html

到了这里,关于《TCP/IP网络编程》阅读笔记--进程间通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《TCP/IP网络编程》阅读笔记--Timewait状态和Nagle算法

            对于服务器端/客户端,当一端结束连接时,会向另一端发送 FIN 消息;两端的在经过四次挥手过程后,其 Socket 不会马上消除,而是会处于一个 Time-wait 状态的阶段,此时 Socket 拥有的 端口号并没有得到释放 ,因此 不能使用相同的端口号 ;         只有先断开连接

    2024年02月09日
    浏览(41)
  • 《TCP/IP网络编程》阅读笔记--getsockopt和setsockopt的使用

    目录 1--Socket的多种可选项 2--getsocketopt() 3--setsockopt() 4--代码实例         Socket 拥有多种可选项,其可分为 SOL_SOCKET 层,IPPROTO_IP 层和IPPROTO_TCP 层等,一般通过 getsocketopt() 和 setsockopt() 函数进行获取和设置; ① 基于  getsockopt() 函数,利用设置协议层为 SOL_SOCKET 和 SO_TYPE 可选项

    2024年02月09日
    浏览(35)
  • 《TCP/IP网络编程》阅读笔记--基于TCP的服务器端/客户端

    目录 1--TCP/IP协议栈 2--TCP服务器端默认函数调用顺序 3--TCP客户端的默认函数调用顺序 4--Linux实现迭代回声服务器端/客户端 5--Windows实现迭代回声服务器端/客户端 6--TCP原理 7--Windows实现计算器服务器端/客户端         TCP/IP协议栈共分 4 层,可以理解为数据收发分成了 4 个层

    2024年02月10日
    浏览(59)
  • 《TCP/IP网络编程》阅读笔记--基于UDP的服务器端/客户端

    目录 1--TCP和UDP的主要区别 2--基于 UDP 的数据 I/O 函数 3--基于 UDP 的回声服务器端/客户端 4--UDP客户端Socket的地址分配 5--UDP存在数据边界 6--UDP已连接与未连接的设置 ① TCP 提供的是可靠数据传输服务,而 UDP 提供的是不可靠数据传输服务; ② UDP 在结构上比 TCP 更简洁,其不会

    2024年02月09日
    浏览(58)
  • 《TCP/IP网络编程》阅读笔记--基于Windows实现Hello Word服务器端和客户端

    目录 1--Hello Word服务器端 2--客户端 3--编译运行 3-1--编译服务器端 3-2--编译客户端 3-3--运行 运行结果:

    2024年02月10日
    浏览(61)
  • 【网络编程】网络通信基础——简述TCP/IP协议

    个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【网络编程】【Java系列】 本专栏旨在分享学习网络编程的一点学习心得,欢迎大家在评论区交流讨论💌 ip地址简单来说就是用来描述网络上一个设备的所在位置。 端

    2024年02月04日
    浏览(56)
  • 网络编程——深入理解TCP/IP协议——OSI模型和TCP/IP模型:构建网络通信的基石

    TCP/IP协议,即 传输控制协议/互联网协议 ,是一组用于在计算机网络中实现通信的协议。它由两个主要的协议组成:TCP(传输控制协议)和IP(互联网协议)。TCP负责确保数据的可靠传输,而IP则负责路由数据包以在网络中传递。TCP/IP协议簇还包含其他辅助协议,如UDP(用户数

    2024年02月14日
    浏览(53)
  • 网络编程day2——基于TCP/IP协议的网络通信

            计算机S                                                 计算机C      创建socket对象                                   创建socket对象      准备通信地址(自己的ip(非公网ip))      准备通信地址                                     (计算

    2024年02月10日
    浏览(64)
  • linux【网络编程】TCP协议通信模拟实现、日志函数模拟、守护进程化、TCP协议通信流程、三次握手与四次挥手

    Tcp通信模拟实现与Udp通信模拟实现的区别不大,一个是面向字节流,一个是面向数据报;udp协议下拿到的数据可以直接发送,tcp协议下需要创建链接,用文件描述符完成数据的读写 1.1.1 接口认识 1.1.1.1 listen:监听socket 1.1.1.2 accept:获取连接 通信就用accept返回的文件描述符,

    2024年02月06日
    浏览(51)
  • Java网络编程之IP,端口号,通信协议(UDP,TCP)

    ① C/S :客户端/服务器 在用户本地需要下载安装客户端程序,在远程有一个服务器端程序。 优点:画面精美,用户体验好 缺点:用户需要下载更新 ② B/S :浏览器/服务器 只需要一个浏览器,用户通过指定网址访问对应的服务器。 优点:不需要开发客户端,只需要页面+服务

    2024年02月03日
    浏览(78)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包