欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

Socket编程(C语言实现)—— 为什么流式传输类似于管道?不区分边界?

发布时间:2025/10/17 43 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Socket编程(C语言实现)—— 为什么流式传输类似于管道?不区分边界? 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

1、管道实现:

(1)代码实现:[root@localhost pipe]# cat pipe.c 

#include <stdio.h> #include <unistd.h>int main(void) {int i = 0;int aiPipe[2] = {0};pid_t stPid = {0};char acSendBuf[2] = {0};char acRecvBuf[4] = {0};if(0 != pipe(aiPipe)){printf("创建管道失败!\n");return 0;}stPid = fork();if(0 == stPid){sleep(2);printf("\n接收的长度是%d\n",read(aiPipe[0], acRecvBuf, sizeof(acRecvBuf)));for(i = 0; i < sizeof(acRecvBuf); i++){printf("acRecvBuf[%d]:%d\n", i, acRecvBuf[i]);}}else{for(i = 0; i < 2; i++){acSendBuf[0] = i + 1;acSendBuf[1] = i + 1;printf("发送长度是%d\n", write(aiPipe[1], acSendBuf, sizeof(acSendBuf)));}}return 0; }

(2)编译执行:[root@localhost pipe]# make pipe

(3)结果显示:

[root@localhost pipe]# ./pipe 发送长度是2 发送长度是2 [root@localhost pipe]# 接收的长度是4 acRecvBuf[0]:1 acRecvBuf[1]:1 acRecvBuf[2]:2 acRecvBuf[3]:2

2、流式传输模式实现——本地进程间通信(AF_UNIX):

(1)代码实现:[root@localhost socket_stream]# cat stream.c

#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h>int main(void) {int i = 0;pid_t stPid = {0};char acSendBuf[2] = {0};char acRecvBuf[4] = {0};stPid = fork();if(0 == stPid){ struct sockaddr_un stAddr = {0};int iNewFD = 0;int iRecvFD = socket(AF_UNIX, SOCK_STREAM, 0);if(0 > iRecvFD){printf("子进程打开socket\n");}remove("./.xx");stAddr.sun_family = AF_UNIX;sprintf(stAddr.sun_path, "./.xx");if(0 != bind(iRecvFD, (void *)&stAddr, sizeof(stAddr))){printf("bind 失败!\n");}listen(iRecvFD, 1000);iNewFD = accept(iRecvFD, NULL, NULL);sleep(2);printf("\n接收的长度是%d\n",read(iNewFD, acRecvBuf, sizeof(acRecvBuf)));for(i = 0; i < sizeof(acRecvBuf); i++){printf("acRecvBuf[%d]:%d\n", i, acRecvBuf[i]);}}else{sleep(1);struct sockaddr_un stAddr = {0};int iSendFD = socket(AF_UNIX, SOCK_STREAM, 0);if(0 > iSendFD){printf("发送socket创建失败!\n");return 0;}stAddr.sun_family = AF_UNIX;sprintf(stAddr.sun_path, "./.xx");if(0 != connect(iSendFD, (void *)&stAddr, sizeof(stAddr))){printf("连接失败!\n");return 0;}for(i = 0; i < 2; i++){acSendBuf[0] = i + 1;acSendBuf[1] = i + 1;printf("发送长度是%d\n", write(iSendFD, acSendBuf, sizeof(acSendBuf)));}}return 0; }

(2)编译执行:[root@localhost socket_stream]# make stream

(3)结果显示:

[root@localhost socket_stream]# ./stream 发送长度是2 发送长度是2 [root@localhost socket_stream]# 接收的长度是4 acRecvBuf[0]:1 acRecvBuf[1]:1 acRecvBuf[2]:2 acRecvBuf[3]:2

3、报式传输模式实现——本地进程间通信(AF_UNIX):

(1)代码实现:[root@localhost socket_dgram]# cat dgram.c 

#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h>int main(void) {int i = 0;pid_t stPid = {0};char acSendBuf[2] = {0};char acRecvBuf[4] = {0};stPid = fork();if(0 == stPid){ struct sockaddr_un stAddr = {0};int iRecvFD = socket(AF_UNIX, SOCK_DGRAM, 0);if(0 > iRecvFD){printf("子进程打开socket\n");}remove("./.xx");stAddr.sun_family = AF_UNIX;sprintf(stAddr.sun_path, "./.xx");if(0 != bind(iRecvFD, (void *)&stAddr, sizeof(stAddr))){printf("bind 失败!\n");}sleep(2);printf("\n接收的长度是%d\n",recvfrom(iRecvFD, acRecvBuf, sizeof(acRecvBuf), 0, NULL, NULL));for(i = 0; i < sizeof(acRecvBuf); i++){printf("acRecvBuf[%d]:%d\n", i, acRecvBuf[i]);}}else{sleep(1);struct sockaddr_un stAddr = {0};int iSendFD = socket(AF_UNIX, SOCK_DGRAM, 0);if(0 > iSendFD){printf("发送socket创建失败!\n");return 0;}stAddr.sun_family = AF_UNIX;sprintf(stAddr.sun_path, "./.xx");for(i = 0; i < 2; i++){acSendBuf[0] = i + 1;acSendBuf[1] = i + 1;printf("发送长度是%d\n", sendto(iSendFD, acSendBuf, sizeof(acSendBuf), 0, (void *)&stAddr, sizeof(stAddr)));}}return 0; }

(2)编译执行:[root@localhost socket_dgram]# make dgram

(3)结果显示:

[root@localhost socket_dgram]# ./dgram 发送长度是2 发送长度是2 [root@localhost socket_dgram]# 接收的长度是2 acRecvBuf[0]:1 acRecvBuf[1]:1 acRecvBuf[2]:0 acRecvBuf[3]:0

由上述代码对比可知,管道与流式传输两种方式得到的结果是一样的,fork出来的只是用来收,父进程用来发数据。
父进程每次发sizeof(acSendBuf),即,两个字节的大小,发两次,共 发送四个字节的大小;
而子进程每次都是用sizeof(acRecvBuf)四个字节来接收数据;
pipe模式与流式传输(socket_stream)两种方式都是,一次性全部四个字节,没有区分是第几次发送过来的数据;
而报式传输只收两个字节大小数据,即,第一个包的大小,若要收全部数据,需要循环接受。
所以综上所述,流式传输与类似于管道。

总结

以上是生活随笔为你收集整理的Socket编程(C语言实现)—— 为什么流式传输类似于管道?不区分边界?的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。