在这里,我试图创build一个简单的客户端和服务器使用pipe道。 我分叉一个进程,使孩子充当客户端和父母作为服务器。 以下是代码:
#include<unistd.h> #include<stdlib.h> #include<stdio.h> #include<string.h> void errorMsg(char* msg) { printf("\n%s\n", msg); // exit(0); } int main() { int servfd[2]; int clntfd[2]; int chldpid; if(pipe(servfd) < 0) errorMsg("Unable to create server pipe.!!"); if(pipe(clntfd) < 0) errorMsg("Unable to create client pipe.!!!"); if((chldpid = fork()) == 0) { char* txt = (char*) calloc(256, sizeof(char)); close(servfd[1]); close(clntfd[0]); printf("@Client: Enter a string: "); //scanf("%s", txt); //or fgets printf("Entered.!!"); int n; txt = "Anything that you want will not be considered no matter what you do!!"; char txt1[256]; write(clntfd[1], txt, 256); //if(txt1[strlen(txt1) - 1] = '\n') //{ printf("asdasdas"); //txt[strlen(txt) - 1] = '\0';} //int i = 0; //for(i = 0; i < 256; i++) //printf("%c", txt1[i]); while((n = read(servfd[0], txt1, 256)) > 0) printf("\nAt client: %d bytes read\n\tString: %s\n", n, txt1); } else { //printf("Parent: \n\n"); close(servfd[0]); close(clntfd[1]); char* txt = NULL; int n, n1; n = read(clntfd[0], &txt, 256); printf("Server read: %d", n); n1 = write(servfd[1], &txt, 256); printf("Server write: %d", n1); wait(chldpid); } exit(0); }
这就是发生的事情。 当我运行该程序,它只打印Anything that yo
(正好16个字符),没有别的。 当我尝试使用注释中显示的for
循环来查看txt1
的完整内容时,发现在txt1
yo
之后txt1
值(天知道从哪里)。 之后,它们应该是正常的内容。 任何想法为什么发生这种情况?
当我尝试在适当的位置打印时,读取和写入的字节数都是正确的。 它打印256 bytes read
。 然而,strlen的txt1
的大小是“16”。 此外,程序在打印部分string后挂起。
当我尝试从用户使用scanf
或fgets
也显示在评论中的string时,程序终止,只要我按下input。 也不知道为什么会发生这种情况。
任何关于行为的见解都会有所帮助。 对不起,有很多问题。 谢谢你的时间。! 我使用的Ubuntu 12.04,如果这可能有任何帮助。
我已经添加了各种意见和更正您的代码。 它现在按预期工作。 你的主要问题是由codeaddict指出,你没有分配缓冲区。 我很惊讶,你没有碰到一个SIGSEGV。
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> void errorMsg(char* msg) { printf("\n%s\n", msg); // exit(0); } // move this into global space and make it const (non modifiable, easyer to debug) const char text_to_send[] = "Anything that you want will not be considered no matter what you do!!"; int main() { int servfd[2]; int clntfd[2]; int chldpid; if(pipe(servfd) < 0) errorMsg("Unable to create server pipe.!!"); if(pipe(clntfd) < 0) errorMsg("Unable to create client pipe.!!!"); if((chldpid = fork()) == 0) { char txt[256]; // You have to actually allocate a buffer (aka enough memory to hold your string. You have allocated a pointer to a buffer, but no actual buffer) close(servfd[1]); close(clntfd[0]); printf("@Client: Enter a string: "); scanf("%s", txt); // since you now actually have a buffer to put the input into this no longer fails printf("Entered.!!\n"); int n; char txt1[256]; write(clntfd[1], text_to_send, sizeof(text_to_send)); // write only as much as you actually have to say, not the whole size of your buffer while((n = read(servfd[0], txt1, 256)) > 0) printf("\nAt client: %d bytes read\n\tString: %s\n", n, txt1); // this is not nessesary at this point, but it is good style to clean up after yourself close(servfd[0]); close(clntfd[1]); } else { //printf("Parent: \n\n"); close(servfd[0]); close(clntfd[1]); char txt[256]; // same here, you need to actually allocate a buffer. int n, n1; n = read(clntfd[0], txt, 256); // read into txt, not &txt. you want to read into your buffer pointed to by txt, not into the part of memory that contains the pointer printf("server read: %d\n", n); n1 = write(servfd[1], txt, n); // do not send the whole buffer, just as much as you have actually useful information in it printf("server write: %d\n", n1); // close the loose file descriptors, else your child will read on them forever close(servfd[1]); close(clntfd[0]); int status; wait(&status); // this is called like this. if you want to use the pid you call waitpid(chldpid, &status, 0); } exit(0); }
在父进程中你正在做:
char* txt = NULL; ..... n = read(clntfd[0], &txt, 256);
这是不正确的,因为你正在读取由txt
指向的缓冲区中的数据,但你没有分配缓冲区! 你所看到的是一个不确定的行为的表现。