2012-12-02 30 views
1

我需要編寫一個程序來通過套接字檢索和處理消息。我毫不費力地理解創建套接字,綁定套接字,偵聽傳入連接並接受它的過程。我無法接收來自已爲接受的連接創建的文件流的消息。我的代碼如下(我已經包括了幾乎所有的以供參考,但我認爲這個問題而來的連接被接受後..):嘗試接受套接字連接,檢索並處理消息,然後將此消息寫入終端

int sockfd; // the socket file descriptor 
int conn_fd; // the accepted connection file descriptor 
FILE *conn_fs; // the file stream for the accepted connection 
char *conn_buff; 
//char conn_buff[LINE_MAX]; // a buffer to store the data received from the accepted connection 

int main(int argc, char *argv[]) { 
int port = 0; 
if ((argc != 2) || (sscanf(argv[1], "%d", &port) != 1)) { 
    fprintf(stderr, "Usage: %s [PORT]\n", argv[0]); 
    exit(1); 
} 

if (port < 1024) { 
    fprintf(stderr, "Port must be greater than 1024\n"); 
    exit(1); 
} 

struct sockaddr_in servaddr; // socket address structure (socket in address) 
// set all bytes in socket address structure to zero, and fill in the relevant data members 
memset(&servaddr, 0, sizeof(servaddr)); 
servaddr.sin_family = AF_INET; 
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
servaddr.sin_port = htons(port); // port is the first argument given in the terminal 

// tell the user the servaddr structure has been initialised. 
//printf("servaddr structure has been initialised..\n\ncreating socket..\n"); 

// create the socket using IPv4 (AF_INET) and 2-way comms (SOCK_STREAM) 
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { // socket() returns < 0 if an error occurs 
    printf("error: creating the socket..\nexitting..\n"); 
    exit(EXIT_FAILURE); 
} 

// tell the user the socket has been created 
//printf("socket created..\n\nbinding socket..\n"); 

// bind the socket to the socket address structure defined above 
if (bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) { // bind() returns < 0 if an error occurs 
    printf("error: binding the socket..\nexitting..\n"); 
    exit(EXIT_FAILURE); 
} 

// tell the user the socket is "bound" 
//printf("socket is now \"bound\"..\n\nmarking the socket as passive..\n"); 

// set the socket to accept incoming connections (listen) 
if (listen(sockfd, SOMAXCONN) < 0) { // listen() returns < 0 if an error occurs 
    printf("error: marking the socket as a passive socket in the function listen()..\nexitting..\n"); 
    exit(EXIT_FAILURE); 
} 

// tell the user the socket is listening for incoming connections 
printf("socket is now passive (listening)..\n\naccepting incoming connections..\n"); 

// accept an incoming connection 
if (conn_fd = accept(sockfd, NULL, NULL) < 0) { // accept() returns < 0 if an error occurs 
    printf("error: accepting an incoming connection..\nexitting..\n"); 
    exit(EXIT_FAILURE); 
} 

// tell the user a connection has been accepted 
printf("a connection has been accepted..\n\ncreating a file stream for this connection..\n"); 
    /* 
// open a file stream associated with conn_fd 
if ((conn_fs = fdopen(conn_fd, "r+")) == NULL) { // fdopen() returns NULL if an error occurs 
    printf("error: associating a stream to the connections file descriptor in the function fdopen()..\nexitting..\n"); 
    exit(EXIT_FAILURE); 
} 

    // echo out the incoming message 
    /*while (fgets(conn_buff, LINE_MAX, conn_fd) != NULL) { // fill the conn_buff buffer with data from the file stream conn_fs. returns NULL on error or EOF 
    //while (read(conn_fd,conn_buff,sizeof(char)*LINE_MAX) > 0) { 
     printf(conn_buff);printf("OH HAIIIIIIIIIIIIIIIIIIIIIIIIII\n"); 
    } printf("OH HAI\n");*/   

    size_t len = 100; 
    ssize_t read; 
    while ((read = getline(&conn_buff, &len, conn_fs)) != -1) { 
     printf("Retrieved line of length %zu :\n", read); 
     printf("%s", conn_buff); 
    } 

    free(conn_buff); 

    // check if there was an error 
    if (ferror(conn_fs) != 0) { // returns nonzero if the error indicator is set for conn_fs (eg, if fgets() above returned NULL due to an error) 
     printf("error: an error occurred whilst retrieving data from the stream..\nexitting..\n"); 
     exit(EXIT_FAILURE); 
    } 

// close the file stream associated with conn_fd 
if (close((int) conn_fs) != 0) { // close the file stream 
    printf("error: closing the file stream..\nexitting..\n"); 
    exit(EXIT_FAILURE); 
} 


exit(EXIT_SUCCESS); 
} 

當我運行程序時,它停止while ((read = getline(...循環內。如果我點擊回車來刷新緩衝區,那麼我會從終端獲得「Retrieved line of length 1:」。我發現程序是(出於某種原因,我不明白)從標準輸入讀取。它等着我輸入任何東西,只要我沖洗緩衝區(即回車),它就會把它全部發回給我。關閉程序的唯一方法是使用Ctrl + C。出於這個原因,我認爲我的if ((conn_fs = fdopen(conn_fd, "r+")) == NULL) {聲明存在問題。 (fread(),read(),getline(),fgets(),fgetc()...),它們都具有相同的效果。然後,當我意識到問題必須與我如何打開文件流,我嘗試使用fopen()但無濟於事。

我可能犯了一個愚蠢的錯誤,但任何人都可以幫助我嗎?

+0

你做的部分if(conn_fs = fdopen(conn_fd,「r +))..似乎被註釋掉了。這是你的原始代碼嗎? –

+0

順便說一下,close((int)conn_fs)是錯誤的。接受不是FILE *的文件描述符參數。 –

回答

0

客戶端永遠不會關閉連接。