我正在通過UNIX網絡編程中的示例工作,並在此處將「daytimeclientserv.c」修改爲此代碼。服務器按照預期向客戶端發送日期/時間字符串,除了啓動時收到的第一個請求。當我第一次運行服務器程序(在局域網中的另一臺計算機上)時,它會創建監聽套接字,將其綁定,然後等待連接。在收到第一個請求時,它將日期/時間字符串打印到它自己的stdout(終端)而不是套接字,並且客戶端程序永遠掛起等待。但是,所有後續請求都會正確發送到客戶端。使用gdb,我注意到connfd總是被設置爲零。它在第一次請求時以及在將來的所有時間都設置爲零。服務器打印到標準輸出而不是套接字
我也有與此相關的一些其他問題:
如果服務器偵聽一個插座(listenfd),然後用連接()重新連接在另一個(connfd),客戶如何交易隨着插座的變化?這是我的理解是一個套接字由四個部分標識:servIPaddr,servPort,clientIPaddr,CLIENTPORT
我怎麼可以運行服務器(在Linux上)而不被根
我怎樣才能乾淨地關閉監聽套接字,以便我可以再次使用它。如果我使用SIGINT(Ctrl-C)退出服務器程序,則會出現綁定錯誤。到目前爲止,我一直在使用gdb,並使用「call close(listenfd)」來手動調用該函數。但有沒有辦法做到這一點,如果我不使用GDB(即只調試客戶端應用程序)。
任何幫助,非常感謝。
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#define BUFFER 80
int main(int argc, char **argv) {
int listenfd, connfd;
char buf[BUFFER];
struct sockaddr_in servaddr;
time_t ticks;
struct sockaddr *ptr;
char *ret;
if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket error");
return 1;
}
memset(&servaddr, 0, sizeof(servaddr));
memset(buf, 0, BUFFER);
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
ptr = (struct sockaddr*) &servaddr;
if (bind(listenfd, ptr ,sizeof(servaddr)) < 0) {
perror("bind error");
return 2;
}
if (listen(listenfd, 128) < 0) {
perror("listen error");
return 3;
}
ptr = NULL;
while (1) {
if (connfd = accept(listenfd, ptr, NULL) < 0) {
perror("accept error");
return 4;
} else {
ticks = time(NULL);
ret = ctime(&ticks);
sprintf(buf, "%.24s\n", ret);
if (write(connfd, buf, strlen(buf)) < 0) {
perror("write error");
close(connfd);
}
}
return 0;
}
我使用-pedantic-錯誤,-Wfatal-錯誤,它編譯罰款 – xst 2012-07-17 19:39:55
好吧,這仍然是錯誤,我的編譯器'-Wall'報告它:_'warning :建議用作真值的賦值周圍的圓括號[-Wparentheses]'_ – sehe 2012-07-17 19:41:53
好的,現在我將使用'-pedantic-errors -Wall -Werror -Wfatal-errors' – xst 2012-07-17 19:47:16