用C编程语言在telnet会话中获取keypress的正确方法是什么?

时间:2013-08-20 11:24:10

标签: c sockets telnet

在套接字应用程序中接受getch()maneer中的keypress的正确方法是什么?我失去了几天试图解决这个问题,而我发现的只是使用各种IAC序列将telnet客户端置于字符模式,但是当我这样做时,我的应用程序不会等待用户输入,看起来就像跳过read()。这是我的代码:

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



int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr, cli_addr;
int clilen;

char sendBuff[1025];
time_t ticks;

listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));

serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000); // listen on port 5000

bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

listen(listenfd, 10);
clilen=sizeof(cli_addr);
while(1)
{
    connfd = accept(listenfd, (struct sockaddr*) &cli_addr, &clilen);
    char mystring[4096];
    strcpy(mystring,"\377\375\003");    // IAC DO SUPPRESS GO AHEAD, put telnet client into character mode
    write(connfd, mystring, strlen(mystring));
    char bafer[4096];

    strcpy(mystring,"\033[2J\033[H"); // clear screen, move cursor to upper left corner
    write(connfd, mystring, strlen(mystring));

    strcpy(mystring,"\033[31;7m"); // red letters     
    write(connfd, mystring, strlen(mystring));

    strcpy(mystring,"\033[0m"); //      reset VT100 colors
    write(connfd, mystring, strlen(mystring));
    strcpy(mystring,"Enter key: ");
    write (connfd, mystring, strlen(mystring));

    read (connfd, bafer, 4095);

    strcpy(mystring, "You pressed: ");
    write (connfd, mystring, strlen(mystring));
    write(connfd, bafer, strlen(bafer));

    close(connfd);
    sleep(1);
 }
}

2 个答案:

答案 0 :(得分:0)

'bafer'未初始化 - 您不能只是将内容读入其中,然后在其上使用strlen()。使用read()的结果在数据末尾推送空终止符,或者根本不使用strlen()(最好是后者)。

哦 - 并使用recv()而不是阅读。

答案 1 :(得分:0)

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

#define IAC_WILL_SGA        "\377\373\003"
#define IAC_WILL_ECHO       "\377\373\001"
#define CLR_SCR             "\033[2J\033[H"
#define RED_LETTERS         "\033[31;7m"

#define IAC     "\377"
#define DONT    "\376"
#define DO      "\375"
#define WONT    "\374"
#define WILL    "\373"
#define SGA     "\003"
#define ECHO    "\001"

int main(int argc, char *argv[])
{
int listenfd = 0, connfd = 0;
struct sockaddr_in serv_addr, cli_addr;
int clilen;

char sendBuff[1025];
time_t ticks;

listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
memset(sendBuff, '0', sizeof(sendBuff));

serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000); // listen on port 5000

bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

listen(listenfd, 10);
clilen=sizeof(cli_addr);
while(1)
{
    connfd = accept(listenfd, (struct sockaddr*) &cli_addr, &clilen);

    char bafer[4096];

    write (connfd, IAC, 1);
    write (connfd, WILL, 1);
    write (connfd, SGA, 1);
    recv (connfd, bafer, 3, MSG_WAITALL);
    int i;
    for (i=0;i<strlen(bafer);i++)
        switch ((unsigned char)bafer[i]) {
            case 255: printf("IAC\n");break;
            case 254: printf("DONT\n");break;
            case 253: printf("DO\n");break;
            case 252: printf("WONT\n");break;
            case 251: printf("WILL\n");break;
            case 3: printf("SUPPRESS-GO-AHEAD\n");break;
            case 1: printf("ECHO\n");break;
        }

    write (connfd, IAC, 1);
    write (connfd, WILL, 1);
    write (connfd, ECHO, 1);
    recv (connfd, bafer, 3, MSG_WAITALL);
    for (i=0;i<strlen(bafer);i++)
        switch ((unsigned char)bafer[i]) {
            case 255: printf("IAC\n");break;
            case 254: printf("DONT\n");break;
            case 253: printf("DO\n");break;
            case 252: printf("WONT\n");break;
            case 251: printf("WILL\n");break;
            case 3: printf("SUPPRESS-GO-AHEAD\n");break;
            case 1: printf("ECHO\n");break;
        }

    write(connfd, CLR_SCR, 7);
    write(connfd, RED_LETTERS, 7);
    write (connfd, "Enter key: ", 11);

do {
    recv (connfd,bafer,1,MSG_WAITALL);
    write(connfd, bafer, 1);
    printf("%d\n",(unsigned char)bafer[0]);
} while (bafer[0]!='I');
    write (connfd, "\n",1);
    write(connfd, "\033[0m", strlen("\033[0m")); // reset color
    close(connfd);
 }
}