1

我正在尝试编写一个 TCP Echo 程序,它应该打开一个 TCP 服务器套接字,接受至少 1 个连接,并回显接收到的任何数据。至少,该程序应在指定端口(exe:端口 4444" 上启动并运行。理想情况下,它会询问端口号(来自命令行、命令行参数或配置文件),尝试在该端口上打开,并报告是否发生错误。

该程序应该使用 windows 或 Linux 中的 telnet 命令或任何操作系统中的任何终端仿真器进行测试。用户使用 Telnet 或超级终端连接到正在运行的程序。输入的任何内容都应立即回显。

到目前为止,我有以下内容:

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


#define MAXCONNECTING 1000    //Max connection requests
#define BUFFERSIZE 128       //limits data sent per loop
#define ECHOPORT 4444


//Error checking function
//Will be called multiple times to check for errors throughout the code

void ERR(char *ERROR) {
    perror(ERROR);
    exit(1);
}

/****************************************************************************
 * Handles the connection. Receive/Send data from/to client
 ****************************************************************************/
void ClientHandle(int sock) {
    char buffer[BUFFERSIZE];
    int received = -1;

    //receive the data
    if ((received = recv(sock, buffer, BUFFERSIZE, 0)) < 0) {
        ERR("Failed to receive message from client");
    }

    //send data and check for more incoming data
    while (received > 0) {
        if (send(sock, buffer, received, 0) != received) {
            ERR("Failed to send data to client");
        }
        if ((received = recv(sock, buffer, BUFFERSIZE, 0)) < 0) {
            ERR("Failed to receive additional data from client");
        }
    }
    close(sock);
}

int main(int argc, char *argv[]) {
    /****************************************************************************
     * Get port number from command line and set to default port
     ****************************************************************************/
    char *endptr;
    short int port;

    if (argc == 2) {
        port = strtol(argv[1], &endptr, 0);
        if (*endptr) {
            fprintf(stderr, "EchoServer: Invalid Port Number.\n");
            exit(EXIT_FAILURE);
        }
    } else if (argc < 2) {
        port = ECHOPORT; //port 4444
    } else {
        fprintf(stderr, "EchoServer: Invalid arguments.\n");
        exit(EXIT_FAILURE);
    }

    /****************************************************************************
     * Server Configuration. Creating the socket
     ****************************************************************************/

    int serversock, clientsock;
    struct sockaddr_in echoserver, echoclient;

    if (argc != 2) {
        fprintf(stderr, "USING: echoserver Port: 4444\n");
        exit(1);
    }
    //Creating the TCP socket
    if ((serversock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
        ERR("Failed to create socket");
    }
    //Constructing the server sockaddr_in structure
    memset(&echoserver, 0, sizeof(echoserver)); //clear struct
    echoserver.sin_family = AF_INET;             //internet ip
    echoserver.sin_addr.s_addr = htonl(INADDR_ANY); //listen to any ip address
    echoserver.sin_port = htons(atoi(argv[1])); //server port


    /*****************************************************************************
     * Bind and Listen
     *****************************************************************************/
    if (bind(serversock, (struct sockaddr *) &echoserver, sizeof (echoserver)) < 0) {
        ERR("Failed to bind the server socket");
    }
    if (listen(serversock, MAXCONNECTING) < 0) {
        ERR("Failed to listen on server socket");
    }

    /*****************************************************************************
     * Accepting the transmission
     *****************************************************************************/
    while (1) {
        unsigned int clientleng = sizeof (echoclient);

        if ((clientsock = accept(serversock, (struct sockaddr *) &echoclient, &clientleng)) < 0) {
            ERR("Failed to accept connection from client");
        }
        fprintf(stdout, "Client connected: %s\n", inet_ntoa(echoclient.sin_addr));
        ClientHandle(clientsock);
    }
    return (0);
}

/*****************************************************************************************/

谁能看到我哪里出错了?我可以使用以下命令在终端中找到程序:g++ EchoServer.cpp -0 EchoServer,然后是:./EchoServer

输出只给我: USING: echoserver Port: 4444

我正在尝试远程登录它,但我对这些东西很陌生。请帮忙!!

4

1 回答 1

0

假设您在当前目录中名为 EchoServer.cpp 的文件中有上述文本框的内容,您可以运行以下代码来演示它的工作原理:

g++ EchoServer.cpp -o EchoServer

编译后,您将在同一目录中拥有一个名为 EchoServer 的可执行文件。

如果您只是调用它,您将收到下面的神秘消息,这意味着要使用可执行文件,您必须告诉它使用哪个端口号。

USING: echoserver Port 4444

为了证明它有效,我们将把这个过程放在后台。为此,我们使用与号 (&) 将其转换为作业。

EchoServer 4444 &

这应该返回一个作业编号和一个进程标识符(你的会不同),因此:

[1] 53912

您可以使用作业命令看到它正在运行:

[1]+  Running                 ./EchoServer 4444 &

您现在可以通过 telnet 访问它以查看它是否正常工作:

telnet localhost 4444

你应该看到:

Trying 127.0.0.1...
Client connected: 127.0.0.1
Connected to localhost.
Escape character is '^]'.

在此之后键入的任何内容都将在您按 Enter 或 Return 时发回给您。尝试输入 Hello 并按回车键。

完成后,您可以按住控制键,然后按住右方括号键(之后您可能必须按回车键)。这将带您进入 telnet 提示符,您应该键入quit离开。

要关闭 EchoServer 可执行文件,您可以将作业带回前台并使用 Control-C 键停止它。假设您的作业是 1(您可以jobs再次运行以检查数字),您可以运行以下命令将其带回前台:

fg 1

您现在有效地处于 EchoServer 进程中,按 Control-C 将结束它。

而已!你完成了。你已经成功地证明了程序的工作。

于 2016-05-29T17:01:26.847 回答