2013-07-25 64 views
-1

我試圖做一個協議(內置TCP ontop的的),可以從客戶端發送字符串端口457.這裏的服務器是我到目前爲止有:我是否正確創建協議?

Server.c

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 

void error(const char *msg) 
{ 
    perror(msg); 
    exit(1); 
} 

int main(int argc, char *argv[]) 
{ 
    int sockfd, newsockfd, portno; 
    socklen_t clilen; 
    char buffer[256]; 
    struct sockaddr_in serv_addr, cli_addr; 
    int n; 
    if (argc < 2) { 
     fprintf(stderr,"ERROR, no port provided\n"); 
     exit(1); 
    } 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if (sockfd < 0) 
     error("ERROR opening socket"); 
    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    portno = atoi(argv[1]); 
    serv_addr.sin_family = AF_INET; 
    serv_addr.sin_addr.s_addr = INADDR_ANY; 
    serv_addr.sin_port = htons(portno); 
    if (bind(sockfd, (struct sockaddr *) &serv_addr, 
      sizeof(serv_addr)) < 0) 
     error("ERROR on binding"); 
    listen(sockfd,5); 
    clilen = sizeof(cli_addr); 
    newsockfd = accept(sockfd, 
         (struct sockaddr *) &cli_addr, 
         &clilen); 
    if (newsockfd < 0) 
     error("ERROR on accept"); 
    bzero(buffer,256); 
    n = read(newsockfd,buffer,255); 
    if (n < 0) error("ERROR reading from socket"); 
    printf("Here is the message: %s\n",buffer); 
    n = write(newsockfd,"U got your messaze",18); 
    if (n < 0) error("ERROR writing to socket"); 
    close(newsockfd); 
    close(sockfd); 
    return 0; 
} 

Client.c

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 

void error(const char *msg) 
{ 
    perror(msg); 
    exit(0); 
} 

int main(int argc, char *argv[]) 
{ 
    int sockfd, portno, n; 
    struct sockaddr_in serv_addr; 
    struct hostent *server; 

    char buffer[256]; 
    if (argc < 3) { 
     fprintf(stderr,"usage %s hostname port\n", argv[0]); 
     exit(0); 
    } 
    portno = atoi(argv[2]); 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 
    if (sockfd < 0) 
     error("ERROR opening socket"); 
    server = gethostbyname(argv[1]); 
    if (server == NULL) { 
     fprintf(stderr,"ERROR, no such host\n"); 
     exit(0); 
    } 
    bzero((char *) &serv_addr, sizeof(serv_addr)); 
    serv_addr.sin_family = AF_INET; 
    bcopy((char *)server->h_addr, 
      (char *)&serv_addr.sin_addr.s_addr, 
      server->h_length); 
    serv_addr.sin_port = htons(portno); 
    if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) 
     error("ERROR connecting"); 
    printf("Please enter the message: "); 
    bzero(buffer,256); 
    fgets(buffer,255,stdin); 
    n = write(sockfd,buffer,strlen(buffer)); 
    if (n < 0) 
     error("ERROR writing to socket"); 
    bzero(buffer,256); 
    n = read(sockfd,buffer,255); 
    if (n < 0) 
     error("ERROR reading from socket"); 
    printf("%s\n",buffer); 
    close(sockfd); 
    return 0; 
} 

我覺得好像我沒有正確設置協議。我是嗎?

+0

你的意思做的*正確*?它工作正常嗎? –

+0

@GrijeshChauhan我想確保我沒有製作http服務器或其他任何東西,而不是我打算做的。恐怕這一點,因爲我提出的協議沒有任何指導或協助任何 – user2420649

+0

不,它不是HTTP/FTP服務,即使你不應該把它的協議,它的一個簡單的TCP應用程序開發用C –

回答

0

您應該首先爲您的協議編寫規範。然後,在審閱它之後,您執行規範。您基本上要求我們對您的協議進行逆向工程。這是創建協議的後退方法。在開始實施之前,你應該已經明確了你的程序需要做什麼。

您的服務器程序充當有限種類的ECHO服務器,因爲客戶端接受的輸入不超過255個字節。無論服務器能夠讀取什麼都會記錄到控制檯,並且將消息U got your messaze作爲響應發送給客戶端。

你可能要解決的一些問題:

  • 儘管可能性不大,有可能是比客戶端發送的內容較少的數據你read()調用返回,即使客戶端發送小於256個字節。例如,如果客戶端一次發送aaaaaaaaaa一個字節,則服務器可能只會看到第一個a,並認爲它是完整的消息。

  • 您不會對寫入已關閉的連接採取預防措施。這可能會生成SIGPIPE,並導致您的程序意外退出。

  • 信號通常可能會中斷您的系統調用。您應該檢測到這種情況並在發生這種情況時重新啓動系統調用。

+0

好吧,我會寫一個規範。謝謝 – user2420649

+0

好,我做到了。https://docs.google.com/document/d/1Qp9Z1SPBECeqeZc_E3n2RfAux9ScZo8OQSYgnRkorL4/edit?usp=sharing – user2420649

+0

@ user2420649:這是一個開始,但並不完全足夠的信息,別人來實現它與[很早就考慮你的描述。版本的HTTP](http://www.w3.org/Protocols/HTTP/AsImplemented.html)。另外,與[STOMP](http://stomp.github.io/stomp-specification-1.1的.html)。 – jxh

0

你有一些不正確的類型:


htons預計uint16_t作爲參數

htons((uint16_t)portno); 

read()write()預計ssize_t

ssize_t n; 

bzero已過時,使用

memset(buffer, 0, sizeof(buffer)); 

bcopy已過時,使用

memmove(server->h_addr, &serv_addr.sin_addr.s_addr, server->h_length); 

NUL終止buffer WH恩read()使用

/* bzero(buffer,256); Not needed */ 
n = read(newsockfd,buffer,255); 
if (n < 0) error("ERROR reading from socket"); 
buffer[n]= '\0'; /* here */ 
printf("Here is the message: %s\n",buffer); 

並注意現代程序使用send()recv()代替read()write()


最後,不要使用幻數

fgets(buffer, 255, stdin); 

代替:

fgets(buffer, sizeof(buffer), stdin); /* 256 */ 

爲什麼255? fgets()函數應該將流中的字節讀入s所指向的數組中,直到讀取n-1個字節,所以256是正確的。