【发布时间】:2020-01-25 10:55:20
【问题描述】:
我有两个程序,一个充当服务器,一个充当客户端。他们应该表现得就像您正在使用 ssh 连接到远程系统一样。客户端发送命令,服务器执行命令并将输出打印到服务器。虽然我的代码正是这样做的,但在第一个命令之后输出会有延迟。例如,如果客户端发送date,服务器将返回日期。如果客户端再次发送date,它将打印message was received,而不是输出。在客户端的第三次输入时,第二个日期将被执行并打印在客户端Here is the message:date 上,依此类推。任何想法都会非常感激。
服务器:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <fcntl.h>
#define MAX_PINS 1
void error(const char *msg){
perror(msg);
exit(1);
}
void exec_comm(int sock,int nerror,char buff[]){
dup2(sock,1);
dup2(nerror,2);
if(system(buff)==-1){
printf("command not found\n");
}
}
int main(int argc, char *argv[]){
int sockfd, newsockfd, portno, pid;
socklen_t clilen;
char buffer[256];
char* comm[20],*cbuff;
struct sockaddr_in serv_addr, cli_addr;
int n,i,done=0,correct=0;
char str[INET_ADDRSTRLEN];
char* args,*pins[MAX_PINS]={"1234"},pin[10];
FILE* fd;
int nerror;
if (argc < 2){
fprintf(stderr, "No port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
memset((char *) &serv_addr, 0, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd,(struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd, 5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
if (inet_ntop(AF_INET, &cli_addr.sin_addr, str, INET_ADDRSTRLEN) == NULL) {
fprintf(stderr, "Could not convert byte to address\n");
exit(1);
}
fprintf(stdout, "The client address is :%s\n", str);
while(1){
bzero(buffer, 256);
n = read(newsockfd, buffer, 255);
sscanf(buffer,"%s\n",buffer);
printf("The message that was read was:\t%s\n",buffer);
if (n < 0) error("ERROR reading from socket");
fprintf(fd,"%s\n",buffer);
if(strcmp(buffer,"exit\n")==0||strcmp(buffer,"exit")==0){
printf("Exiting...\n");
done=1;
break;
}
exec_comm(newsockfd,nerror,buffer);
printf("Here is the message: %s\n", buffer);
n = write(newsockfd, "message received", 17);
if (n < 0) error("ERROR writing to socket");
}
fclose(fd);
close(newsockfd);
close(sockfd);
return 0;
}
客户:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(const char *msg){
perror(msg);
exit(0);
}
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 port\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");
n = write(sockfd, stdin, sizeof(int));
if (n < 0)
error("ERROR writing to socket");
do{
printf("Please enter the message: ");
bzero(buffer, 256);
fgets(buffer, 255, stdin);
if(strcmp(buffer,"exit\n")==0||strcmp(buffer,"exit")==0){
printf("Exiting...\n");
n = write(sockfd, buffer, strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
close(sockfd);
break;
}
n = write(sockfd, buffer, strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer, 256);
n = read(sockfd, buffer, 255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n", buffer);
}while(1);
return 0;
}
【问题讨论】:
-
为什么服务器会忽略第一次读取加载的数据——循环之前的那个?
-
糟糕,忘记删除了。我现在删除了它。