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]:22、流式傳輸模式實現——本地進程間通信(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]:23、報式傳輸模式實現——本地進程間通信(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语言实现)—— 为什么流式传输类似于管道?不区分边界?的全部內容,希望文章能夠幫你解決所遇到的問題。

- 上一篇: Socket编程(C语言实现)——UDP
- 下一篇: Socket编程(C语言实现)—— AF