代号3.1415927 2021-07-29 15:14 采纳率: 50%
浏览 31
已结题

如何把telnet 客户端功能拆分开?

这个代码可以在Linux实现telnet 链接,现想把它分成几个模块(链接部分,数据读取部分,关闭链接)。我对这不太懂(这代码是从别处找的,试了一下发现不能单独实现一个功能)我想分开实现这几个功能(连接、读写、关闭链接),应该怎么做?各位给个提示或者思路

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

#define ERR_EXIT(m, ...) do{fprintf(stderr,m"\n",##__VA_ARGS__);loog(m"\n",##__VA_ARGS__);exit(EXIT_FAILURE);}while(0)
#define MAX_BUFF_LEN 1024

void loog(const char *fmt, ...)
{
    char buffer[MAX_BUFF_LEN] = {0};
    va_list args;
    time_t timep;
    time(&timep);
    struct tm *p = gmtime(&timep);
    FILE* fp = fopen("telnet.log", "a+");
    if(fp)
    {
        snprintf(buffer, MAX_BUFF_LEN, "[%.4d-%.2d-%.2d %.2d:%.2d:%.2d][%d]", (1900+p->tm_year),(1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec, getpid());
        va_start(args, fmt);
        vsnprintf(buffer + strlen(buffer), MAX_BUFF_LEN - strlen(buffer) - 1, fmt, args);
        va_end(args);
        fwrite(buffer, strlen(buffer), 1, fp);
        fclose(fp);
    }
}

ssize_t writen(int fd, const void *vptr, size_t n)//Write "n" bytes to a descriptor.
{
    size_t  nleft;
    ssize_t  nwritten;
    const char *ptr;
    ptr = vptr;
    nleft = n;
    while (nleft > 0) 
    {
        if ( (nwritten = write(fd, ptr, nleft)) <= 0) 
    {
            if (nwritten < 0 && errno == EINTR)
                nwritten = 0;  //and call write() again 
            else
                return(-1);   //error 
        }
        nleft -= nwritten;
        ptr   += nwritten;
    }
    return(n);
}

int main(int argc,char **argv)
{
    printf("maincccccccc!");
    if(argc < 3)
    {
        fprintf(stderr, "Usage: %s ServerIPAddress ServerPort\n",argv[0]);
        return 0;
    }
    
    fd_set rset;
    FD_ZERO(&rset);
    int sock = socket(AF_INET,SOCK_STREAM,0);
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;    //internet协议族
    struct hostent *h = gethostbyname(argv[1]);
    server_addr.sin_addr = *((struct in_addr *)h->h_addr);
    server_addr.sin_port = htons(atoi(argv[2]));
    if(connect(sock,(struct sockaddr*)&server_addr, sizeof(struct sockaddr_in)) < 0)
    {
        ERR_EXIT("connect to %s:%sfailed", argv[1],argv[2]);
    }
    fprintf(stdout, "% 9d\n", getpid());
printf("mainddddddddd!");
    fflush(stdout);

    int nready;  
    int maxfd;  
    int fd_stdin = fileno(stdin);
    int fd_stdout = fileno(stdout);
    if (fd_stdin > sock)  
        maxfd = fd_stdin;  
    else  
        maxfd = sock;  
    char sendbuf[1024*4] = {0};  
    char recvbuf[1024*4] = {0};  

    while (1)
    {  
        FD_SET(fd_stdin, &rset);  
        FD_SET(sock, &rset);  
        nready = select(maxfd + 1, &rset, NULL, NULL, NULL); //select返回表示检测到可读事件  
        if (nready == -1) ERR_EXIT("select error");  
        if (nready == 0) continue;  

        if (FD_ISSET(sock, &rset))
        {  
            int ret = read(sock, recvbuf, sizeof(recvbuf)); //按行读取  
            if (ret == -1) ERR_EXIT("read from socket error");  
            else if (ret  == 0) ERR_EXIT("server close");  //服务器关闭  

            writen(fd_stdout, recvbuf, ret);
            memset(recvbuf, 0, sizeof(recvbuf));  
        }
  
       if (FD_ISSET(fd_stdin, &rset))
        {  
            int ret = read(fd_stdin, sendbuf, sizeof(sendbuf));
            if(ret > 0) 
        {
                writen(sock, sendbuf, ret);  
                memset(sendbuf, 0, sizeof(sendbuf));
            }
        else
        {
                ERR_EXIT("read from stdin error");                
            }
        } 

    }  

    close(sock);  
    exit(0);
}

  • 写回答

1条回答 默认 最新

  • 浪客 2021-07-29 16:40
    关注

    各部分提出来写成函数,

    
    int main(int argc,char **argv)
    {
    ////////////////////////连接
        printf("maincccccccc!");
        if(argc < 3)
        {
            fprintf(stderr, "Usage: %s ServerIPAddress ServerPort\n",argv[0]);
            return 0;
        }
        fd_set rset;
        FD_ZERO(&rset);
        int sock = socket(AF_INET,SOCK_STREAM,0);
        struct sockaddr_in server_addr;
        memset(&server_addr, 0, sizeof(server_addr));
        server_addr.sin_family = AF_INET;    //internet协议族
        struct hostent *h = gethostbyname(argv[1]);
        server_addr.sin_addr = *((struct in_addr *)h->h_addr);
        server_addr.sin_port = htons(atoi(argv[2]));
        if(connect(sock,(struct sockaddr*)&server_addr, sizeof(struct sockaddr_in)) < 0)
        {
            ERR_EXIT("connect to %s:%sfailed", argv[1],argv[2]);
        }
        fprintf(stdout, "% 9d\n", getpid());
    printf("mainddddddddd!");
        fflush(stdout);
        
    ////////////////////////读写    
        int nready;  
        int maxfd;  
        int fd_stdin = fileno(stdin);
        int fd_stdout = fileno(stdout);
        if (fd_stdin > sock)  
            maxfd = fd_stdin;  
        else  
            maxfd = sock;  
        char sendbuf[1024*4] = {0};  
        char recvbuf[1024*4] = {0};  
        while (1)
        {  
            FD_SET(fd_stdin, &rset);  
            FD_SET(sock, &rset);  
            nready = select(maxfd + 1, &rset, NULL, NULL, NULL); //select返回表示检测到可读事件  
            if (nready == -1) ERR_EXIT("select error");  
            if (nready == 0) continue;  
            if (FD_ISSET(sock, &rset))
            {  
                int ret = read(sock, recvbuf, sizeof(recvbuf)); //按行读取  
                if (ret == -1) ERR_EXIT("read from socket error");  
                else if (ret  == 0) ERR_EXIT("server close");  //服务器关闭  
                writen(fd_stdout, recvbuf, ret);
                memset(recvbuf, 0, sizeof(recvbuf));  
            }
           if (FD_ISSET(fd_stdin, &rset))
            {  
                int ret = read(fd_stdin, sendbuf, sizeof(sendbuf));
                if(ret > 0) 
            {
                    writen(sock, sendbuf, ret);  
                    memset(sendbuf, 0, sizeof(sendbuf));
                }
            else
            {
                    ERR_EXIT("read from stdin error");                
                }
            } 
        }  
    ///////////////////////关闭
        close(sock);  
        exit(0);
    }
     
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 8月4日
  • 已采纳回答 8月2日
  • 修改了问题 7月29日
  • 创建了问题 7月29日

悬赏问题

  • ¥15 java 操作 elasticsearch 8.1 实现 索引的重建
  • ¥15 数据可视化Python
  • ¥15 要给毕业设计添加扫码登录的功能!!有偿
  • ¥15 kafka 分区副本增加会导致消息丢失或者不可用吗?
  • ¥15 微信公众号自制会员卡没有收款渠道啊
  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘