我应该在Linux上使用客户端在与服务器连接的套接字上编写C程序,提供登录凭据,服务器根据文件验证这些凭据,然后根据有效/无效状态返回不同的消息
到目前为止,我的服务器代码是:
#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);
}
}
我的问题是: 键入用户名并按Enter键之后,客户端或服务器端均不会发生任何反应。为什么?
答案 0 :(得分:0)
在客户端代码中调用endwin()
之前,请先从服务器检查响应,即密码是否有效。如果无效,则可以重新输入两次或类似内容,然后发布“拒绝访问”消息。
您可以通过结合使用循环和操纵ncurses窗口来实现密码的三次输入,请参见以下伪代码:
//bool pw_valid=false; https://stackoverflow.com/questions/1921539/using-boolean-values-in-c
int pw_valid=0; // 0 is false and 1 is true
for(int i=0; i<3; i++)
{
manipulate curses screen to (re-)enter password; check if password is valid (ask server, create new response on the server that verifies valid or invalid password check...) and set pw_valid accordingly;
if(pw_valid==1){printw("Password is valid!\n"); break;}
}
if(pw_valid==0) printw("Access denied!\n");
endwin(); //https://linux.die.net/man/3/endwin
关键是break;
指令,您无需输入三次密码即可退出循环。
有关curses命令和curses C ++示例,另请参见 http://www.cs.ukzn.ac.za/~hughm/os/notes/ncurses.html 和 http://www.cplusplus.com/articles/E6vU7k9E/#CURSES