Программирование Socket - Простой клиент / сервер - PullRequest
1 голос
/ 09 февраля 2020

Я должен написать программу в C на Linux, используя сокеты, где клиенты подключаются к серверу, предоставляют учетные данные для входа, сервер проверяет эти учетные данные в файле, а затем возвращает другое сообщение в зависимости от действительный / недействительный статус.

Пока мой код сервера:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <curses.h>

void error(char *msg)
{
    perror(msg);
    exit(1);
}

void sendResponse(int newsockfd, int n)
{
    n = write(newsockfd, "Welcome to CPSC445-Comp Networking class\nYou are invited to use Fortnight", 73);
    if (n < 0)
    {
        error("ERROR writing to socket");
    }
}

void sendResponse1(int newsockfd, int n)
{
    n = write(newsockfd, "Only for ESU CPSC students taking CPSC445\nYou are not yet invited", 66);
    if (n < 0)
    {
        error("ERROR writing to socket");
    }
}

int readPass(int newsockfd, int n, char buffer[], int i)
{
    int u = i;
    bzero(buffer, 256);
    n = read(newsockfd,buffer,255);
    if (n < 0)
    {
        error("ERROR reading from socket");

    }


    char newbuf[256];
    char user[8];
    char pass[8];
    FILE *f1;

    f1 = fopen("passwd.txt", "r");

    for (int i = 0; i<=u; i++)
    {   
        fgets(newbuf, 256, f1);
        sscanf(newbuf, "%[^:]_%[^:]", user, pass);;
    }
    if (strcmp(buffer, pass) == 0)
    {
        n = write(newsockfd, "1", 1);
        sendResponse(newsockfd, n);
        return 1;
    }
    else
    {
        n = write(newsockfd, "Invalid password, please try again\n", 33);
        return 0;
    }
    sendResponse1(newsockfd, n);
    return 0;
}

int readUser(int newsockfd, int n, char buffer[])
{
    bzero(buffer, 256);
    n = read(newsockfd,buffer,255);
    printf("%s", buffer);

    if (n < 0)
    {
        error("ERROR reading from socket");

    }

    char valid[1];  
    char newbuf[256];
    char user[8];
    FILE *f1;

    f1 = fopen("passwd.txt", "r");

    int i = 0;
    while (!feof(f1))
    {   
        fgets(newbuf, 256, f1);
        sscanf(newbuf, "%[^:]", user);
        if (strcmp(buffer, user) == 0)
        {
            n = write(newsockfd, "1", 1);
            readPass(newsockfd, n, buffer, i);
            return 1;
        }
        else
        {
            i++;
        }
    }
    n = write(newsockfd, "Invalid username, please try again\n", 34);
    return 0;    
}



int main(int argc, char *argv[])
{
    pid_t cli2, cli3;
    int sockfd, newsockfd, portno, clilen;
    int cli_num = 0;
    int clients[3];
    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_port = htons(portno);
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
    {
        error("ERROR on binding");
    }
    listen(sockfd, 5);
    clilen = sizeof(cli_addr);

    //cli2 = fork();
    //cli3 = fork();
    newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);

    if (newsockfd < 0) 
    {
        error("ERROR on accept");
    }

    readUser(newsockfd, n, buffer);
    return 0;
}

И мой код клиента:

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ncurses.h>

void error(char *msg)
{
    perror(msg);
    exit(0);
}

void sendUser(int sockfd, int n, char buffer[], WINDOW *login)
{
    bzero(buffer, 256);
    getstr(buffer);
    n = write(sockfd, buffer, strlen(buffer));
    if (n = 0)
    {
        error("ERROR writing to socket");
    }
}

void sendPass(int sockfd, int n, char buffer[], WINDOW *login)
{
    bzero(buffer, 256);
    noecho();
    cbreak();

    int i = 0;
    while(1)
    {
        int temp = getch();
        if (temp == 10)
        {
            break;  
        }
        else
        {
            buffer[i] = temp;
            addch('*');
            i++;
        }
    }
    n = write(sockfd, buffer, strlen(buffer));
    if (n = 0)
    {
        error("ERROR writing to socket");
    }
}

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 post\n", argv[0]);
        exit(0);
    }
    portno = atoi(argv[2]);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        error("ERROR opening socket");
    }
    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);
    if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
    {
        error("ERROR connecting");
    }

    char valid[1];
    WINDOW *login = initscr();

    int tries = 3;
    for (int i = 0; i<3; i++)
    {
        waddstr(login, "\nWelcome to Computer Science Department\n\n");
        waddstr(login, "Login: ");
        sendUser(sockfd, n, buffer, login);
        n = read(sockfd, valid, 1);

        if (strcmp(valid, "1") == 0)
        {
            valid[0] = 0;
            waddstr(login, "Password: ");
            sendPass(sockfd, n, buffer, login);
            n = read(sockfd, valid, 1);

            if (strcmp(valid,"1") == 0)
            {
                endwin();
                bzero(buffer, 256);
                n = read(sockfd, buffer, 255);
                if (n = 0)
                {
                    error("ERROR reading from socket");
                }
                printf("%s\n", buffer);
                break;
            }
            else
            {
                endwin();
                tries--;
                bzero(buffer, 256);
                n = read(sockfd, buffer, 255);
                if (n = 0)
                {
                    error("ERROR reading from socket");
                }
                printf("%s\n", buffer);
            }
        }
        else
        {
            endwin();
            tries--;
            bzero(buffer, 256);
            n = read(sockfd, buffer, 255);
            if (n = 0)
            {
                error("ERROR reading from socket");
            }
            printf("%s\n", buffer);
        }
    }
    if (strcmp(valid, "1") == 0)
    {
        return 0;
    }
    else
    {
        bzero(buffer, 256);
        n = read(sockfd, buffer, 255);
        if (n = 0)
        {
            error("ERROR reading from socket");
        }
        printf("%s\n", buffer);
    }
}

Мой вопрос: после того, как имя пользователя и нажмите клавишу ввода, ничего не происходит ни на стороне клиента, ни на стороне сервера. Почему?

1 Ответ

0 голосов
/ 09 февраля 2020

Перед вызовом endwin() в клиентском коде проверьте ответ от сервера, т.е. пароль действителен или нет. Если он недействителен, дайте возможность повторно ввести два раза или что-то еще, а затем отправить сообщение «Доступ запрещен». Вы можете реализовать тройной ввод пароля, используя al oop в сочетании с манипулированием окном ncurses, см. Следующий псевдокод:

Критически важна инструкция break;, которую вы можете оставить l oop без необходимости ввода пароля три раза.

Также см.

http://www.cs.ukzn.ac.za/~hughm/os/notes/ncurses.html и http://www.cplusplus.com/articles/E6vU7k9E/#CURSES для команд curses и примеров curses C ++
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...