2014-09-23 121 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