2014-09-23 123 views
1

我正在嘗試爲它們之間發送協商的Telnet客戶端服務器會話編寫代碼。像Will一樣,不會,不會。我使用socket編程編寫了一個基本的客戶端服務器程序。 如果我能知道如何通過協商將客戶端/服務器修改爲telnet客戶端服務器,那將會非常有幫助。以下是代碼:與談判的Telnet客戶端服務器會話

提前這裏

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


char buf1[] = {0xff, 0xfb, 0x18, 0xff, 0xfb, 0x1f}; 
char buf2[] = {0xff, 0xfc, 0x20, 0xff, 0xfc, 0x23, 0xff, 0xfb, 0x27}; 
char buf3[] = {0xff, 0xfa, 0x1f, 0x00, 0x78, 0x00, 0x32, 0xff, 0xf0}; 
char buf4[] = {0xff, 0xfa, 0x27, 0x00, 0xff, 0xf0, 0xff, 0xfa, 0x18, 0x00, 0x41, 0x4e, 0x53, 0x49, 0xff, 0xf0}; 
char buf5[] = {0xff, 0xfd, 0x03}; 
char buf6[] = {0xff, 0xfb, 0x01, 0xff, 0xfe, 0x05, 0xff, 0xfc, 0x21}; 
char buf7[] = {0xff, 0xfc, 0x01}; 
char buf8[] = {0xff, 0xfd, 0x01}; 

void read (int sock) 
{ 
    char buffer[256]; 

    /* Now read server response */ 
    memset(buffer, 0, sizeof(buffer)); 
    int n = recv(sock, buffer, 255, 0); 
    if (n < 0) 
    { 
     perror("ERROR reading from socket"); 
     return; 
    } 
    printf("%d bytes received buffer is: %s\n", n, buffer); 
    for (int i = 0; i < n; i++) 
     printf("%2x ", buffer[i]); 
    printf("\n"); 
} 

void mwrite (int sock, char * buf, int size) 
{ 
    int n = send(sock, buf, size, 0); 
    if (n < 0) 
    { 
     perror("ERROR writing to socket"); 
     return; 
    } 
    printf("Bytes Sent: %d\n", n); 
    } 

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]); 
     return(0); 
    } 
    portno = atoi(argv[2]); 
    /* Create a socket point */ 
    sockfd = socket(AF_INET, SOCK_STREAM, 0); 

    if (sockfd < 0) 
    { 
     perror("ERROR opening socket"); 
     return(1); 
    } 
    server = gethostbyname(argv[1]); 
    if (server == NULL) 
    {fprintf(stderr,"ERROR no such host \n"); 
    exit(0);} 


    //printf("host %s, port %d\n", host.c_str(), portno); 

    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_addr.s_addr = inet_addr(host.c_str()); // ("127.0.0.1"); 
    serv_addr.sin_port = htons(portno); 

    /* Now connect to the server */ 
    if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) 
    { 
     perror("ERROR connecting"); 
     return(1); 
    } 

printf("Please enter the message="); 
bzero(buffer,256); 
fgets(buffer,255,stdin); 

n= write(sockfd,buffer,strlen(buffer)); 
if(n<0) 
printf("ERROR writing in socket %d len %d", n, strlen(buffer)); 
bzero(buffer,256); 

n = read(sockfd, buffer, 255); 
if(n<0) 
perror("ERROR reading from socket"); 

printf("%s\n",buffer); 
close(sockfd); 



return 0; 

    buffer[0] = 0x0d; 
    buffer[1] = 0x0a; 
    mwrite (sockfd, buffer, 2); 
    printf("read 1 "); 
    read(sockfd); 

    mwrite(sockfd, buf1, sizeof(buf1)); 
    sleep(2); 
    mwrite(sockfd, buf2, sizeof(buf2)); 
    printf("read 2 "); 
    read(sockfd); 

    mwrite(sockfd, buf3, sizeof(buf3)); 
    printf("read 3a "); 
    read(sockfd); 
    sleep(2); 
    mwrite(sockfd, buf4, sizeof(buf4)); 
    printf("read 3b "); 
    read(sockfd); 

    mwrite(sockfd, buf5, sizeof(buf5)); 
    sleep(2); 
    mwrite(sockfd, buf6, sizeof(buf6)); 
    printf("read 4 ");  
    read(sockfd); 

    mwrite(sockfd, buf7, sizeof(buf7)); 
    sleep(2); 
    mwrite(sockfd, buf8, sizeof(buf8)); 
    read(sockfd); 

    mwrite (sockfd, buffer, 2); 
    read(sockfd); 

    return 0; 
} 

輸入代碼Server.cpp

enter code here : 

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


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

int main(int argc, char *argv[]) 
{ 

int sockfd, newsockfd, portno; 
//unsigned clilen; 
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,"I got your message",18); 

if (n < 0) 
{ 
error("ERROR writing to socket"); 
} 
return 0; 
} 

感謝。

+2

我建議不要在緩衝區中使用「幻數」。 ''arpa/telnet.h>'頭文件包含你需要的所有常量。使用它們會使這些緩衝區至少更具可讀性。 – 2014-09-23 15:43:43

回答

4

[它開始是太多意見,所以我寫一個答案,而不是]

至於你的問題,它實際上不是一個單一的問題,而是兩個混雜問題:緩衝和談判。您需要緩衝,因爲TCP是一種流媒體協議,接收呼叫可能只接收telnet消息的一部分,而發送呼叫可能只發送一部分telnet消息。第二個問題是談判,爲此你需要一個所謂的狀態機。每個選項你需要一個狀態。

您還需要閱讀並理解RFC854RFC855。請參閱Telnet Wikipedia article以獲取RFC的完整列表。

對於期權協商,WILLWONTDODONT作出響應。除非您已收到WILLWONT,否則通常不應發送DODONT。對於初學者來說,除非您正確處理選項,否則無論何時獲得WILL(或課程WONT)消息,我都建議您始終以DONT回答。除非您確實需要談判某個選項,否則請勿發送WILLWONT


更多實現的角度來看,我建議四個態表,每一個WILLWONTDODONT就差了。這些表格包含簡單的布爾值,告訴您是否已將相應的消息發送給對等體。這四張表格假設您收到的任何未識別的選項都會以DONTWONT回答。

如果您發送WILL,則將其標記在相應的狀態表中,以便在收到DODONT的選項時,您知道是您啓動了協商。

+0

它不一定需要用狀態機來實現。其他健壯且合規的實施方法是可能的。然而,狀態機可以說是最清晰的,並且在穩健性方面可能是最簡單的方法,所以推薦使用+1。 – blubberdiblub 2017-01-03 09:28:27

相關問題