我正在爲分佈式系統類進行分配。我是C.S.的碩士生,但我在編程方面的專長是.NET,我正在開發一個需要一些相當參與的Unix知識的項目,這讓我感到沮喪。嘗試將數據從子進程服務器傳送到其父進程
該任務正在實施刷新通道協議API。所以我正在編寫一個小函數庫,其他應用程序可以實現使用刷新通道通信。我已經設置好了,所以當init函數被調用時,它會派生一個子進程來充當傳入消息的服務器。通過管道將傳入數據發送給父級,子級與父級進程通信。
如果一次發送和接收一條消息,則可以正常工作;例如,
發送 - >接收 - >發送 - >接收 - >等
然而,如果多個消息在做任何接收之前發送;例如,
發送 - >發送 - >發送 - >收到
然後它就會搞砸。特別是,第一條消息被正確接收,但是當我去接收第二條消息時,程序掛起並需要被終止。我在網上做了很多搜索,並且在這個數小時之內一直在堵塞,但還沒有取得很大的進展。
該程序整體來說太大而不能在這裏顯示,但這裏是最相關的位。這是我得到服務器並接收消息的部分。注意行
write(fd [1],buffer,(strlen(buffer)+1));
- 我認爲這是一個很好的候選人,可以成爲問題的根源,但不知道該做什麼不同。 (嘗試的fwrite()和未在所有的工作。)
fd = malloc(2 * sizeof(int));
int nbytes;
if (pipe(fd) < 0) {
perror("Could not create pipe");
return -1;
}
pID = fork();
if (pID < 0) {
perror("Failed to fork");
return -1;
} else if (pID == 0) { // child
close(fd[0]); // close input side of pipe
int cc;
int fsize;
struct sockaddr_in from;
int serials[500];
int i;
for (i = 0; i < 500; i++) serials[i] = 0;
char buffer[2048];
while (1) {
fsize = sizeof(from);
cc = recvfrom(socketNo, buffer, 2048, 0, (struct sockaddr*)&from, &fsize);
if (cc < 0) perror("Receive error");
datagram data = decodeDatagram(buffer);
if (serials[data.serial] == 0) {
write(fd[1], buffer, (strlen(buffer)+1));
serials[data.serial] = 1;
}
}
} else { // parent
close(fd[1]); // close output side of pipe
return 0;
}
(其中「連續」陣列爲不轉發重複的消息,因爲消息被髮送多次,以提高可靠性。我知道的固定大小對於這個數組是不好的做法,但因此它在這方面確定此任務測試不發送很多消息)
接收功能的開頭是這樣的:
int fRecv(int* id, char* buf, int nbytes) {
checkDatagramTable(*id);
char* tbuf = malloc((nbytes + 9) * sizeof(char));
int rbytes = read(fd[0], tbuf, nbytes + 9);
「+9」用於容納隨附的附加信息要發送的消息,用於刷新頻道排序。這也是一個非常粗略的領域,但分配更多的空間是非常有用的,這並沒有幫助解決問題。
我知道這裏有很多無關的東西,對其他函數的引用等。但問題肯定在於我如何通過管道傳輸數據,所以我的問題的來源應該在某處。
在此先感謝您的幫助;這是真正的讚賞。
你分配通過'而(1)'循環一個新的'buffer'每一次旅行 - - 爲什麼?我不明白爲什麼它是動態分配的而不是堆棧分配的,我不明白爲什麼它會在這個函數之外持續存在。 – sarnold
順便說一句,'strace(1)'在嘗試追查問題時非常有用。這就像每個系統調用的免費的'printf(3)'行。 – sarnold
我不記得我爲什麼那樣做,但顯然有一個很好的理由,因爲將它改爲堆棧分配會導致編譯器給出一些非常不祥的警告。爲什麼?你認爲這與我遇到的問題有關嗎? – user1056100