c++ - 如何使用 Telnet 库从服务器发送查询并从客户端接收回显

标签 c++ c telnet

我编写了一个套接字程序,其中客户端将存储在字符缓冲区中的 Telnet 协商发送到服务器。服务器收到它并用每个缓冲区的消息长度进行响应。代码如下:

服务器.cpp

#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 <arpa/telnet.h>
#include <unistd.h>


void error(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)
{
perror("ERROR opening socket");
exit(1);
}

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)
{
perror("ERROR on binding");
exit(1);
}

    if(listen(sockfd,5)<0)
     {
       perror("Error on listen");
     }
       while(1)
      {
    clilen = sizeof(cli_addr);
    newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);

    if (newsockfd < 0)
    {
     perror("ERROR on accept");
     exit(1);
    }

    //fork to hande this client
       if (fork() == 0)
       {  // client code no longer need this;
         close(sockfd);
          // loop until a closed or error state happens
         ssize_t n =0;
         while ((n = read(newsockfd,buffer,sizeof(buffer)-1))>0)
         {
           printf("Recieved : %*s\n",static_cast<int>(n),buffer);

           //send response
           static const char resp[] = "I got yout message \n";

           n = write(newsockfd, resp , sizeof(resp)-1);
           if(n<0)
            {
             perror("Error writing to socket ");
             exit(1);
            }
          }
      close(newsockfd);
      exit(0);
   }
    close(newsockfd); }
return 0;
}

客户端.cpp

#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>
#include <arpa/telnet.h>


char buf1[] = {0xff, 0xfb, 0x18, 0xff, 0xfb, 0x1f};                  


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("\n%d bytes received buffer is: %s", n, buffer);
    for (int i = 0; i < n; i++)
         printf("%2x ", buffer[i]);//printing ascii characters
    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);}




    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 );

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



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


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

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





    bzero(buffer,256);
    buffer[0] = 0x0d;
    buffer[1] = 0x0a;

    printf("\nSend buff....");
    mwrite ( sockfd, buffer,2);
    read(sockfd);

    mwrite( sockfd, buf1, sizeof(buf1));
    printf("\nSend buff1....");
    read(sockfd);


    printf("\nRecieved all negotiation  buffers");

    close(sockfd); // close socket

    return 0;

输出是: 客户端输出:

debian:~/echoserver$ ./client 127.0.0.1 8088
I got your message 

Send buff....Bytes Sent: 2

20 bytes received buffer is: I got yout message 
49 20 67 6f 74 20 79 6f 75 74 20 6d 65 73 73 61 67 65 20  a

Send buf1....Bytes Sent: 6

20 bytes received buffer is: I got yout message 
49 20 67 6f 74 20 79 6f 75 74 20 6d 65 73 73 61 67 65 20  a 
Recieved all negotiation  buffers 

服务器输出:

@debian:~/echoserver$ ./server 8088
Recieved : .N=�� 
Recieved : 
=�� 

我还想知道我们是否要反转这个过程,即从服务器向客户端发送一个 3 字节的查询序列,其中 byte1-Interpret as command(0xff),byte2-命令代码,byte3-选项代码. Telnet 是流式传输的,因此收到的消息可能包含一个或多个查询。例如,服务器在接受连接时发送一个 3 字节的消息 (ff , fd , 18 )。客户端应该只回显 Won't(ff , fc , 18)

例如:

Server : Sending Query 1 : 0xff,0xfd,0x18
Client echo : 0xff , 0xfc , 0x18

提前致谢。

最佳答案

您的 buf 数组不是字符串(没有终止 '\0' 字符),但您对它们调用了 strlen()。那会给你未定义的行为。由于它们是二进制数组,因此请改用 sizeof

这在您自己的跟踪 printf() 中清晰可见,第一行显示“Bytes Sent: 18”,但显然 buf1只有 6 个字节。

关于c++ - 如何使用 Telnet 库从服务器发送查询并从客户端接收回显,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26182019/

相关文章:

c++ - wxWidgets编译错误( fatal error LNK1120 : 26 unresolved externals)

c++ - 如何更正下面的 C++ 代码?

c++ - g++ 4.7.1 编译错误 : conflicting types for ‘strsignal’

c - 在 C 中如何获取指向 char 字符串的指针数组中的项数

ftp - Telnet 和被动 FTP

java - 如何通过 Telnet 发送字符串?

c++ - 如何使用 C++ 和 L-Systems 在空间中的任何给定点和方向生成 3d 树?

c - 如何在应用程序中使用 Sphinx3

c - 这行代码是什么意思?

linux - 通过套接字连接发送 GUI/TUI