我正在尝试基于套接字通信进行命令行。我唯一的问题是执行 exexvp 后(并且数据正在客户端上打印),客户端关闭,我想让他保持事件状态。
这是我的代码:
客户端.c
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/types.h>
#include <netdb.h>
#define PORT_NUMBER 1754
#define HOST_NUMBER
void error(const char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, port_number, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[256];
if (argc < 3) {
//fprintf(stderr, "usage %s hostname port\n", argv[0]);
//first parameter is ip address
printf("usage %s hostname port\n", argv[0]);
exit(0);
}
port_number = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0 )
error("ERROR opening socket!Socket failed!");
printf("Trying to connect...\n");
server = gethostbyname(argv[1]); //ip address
if (server == NULL) {
error( "ERROR, no such host");
//fprintf(stderr, "ERROR, no such host\n"); exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET; //AF_UNIX
bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(port_number);
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR connecting");
printf("Connected!\n");
printf("%s_>\n",argv[1]);
while(1) {
printf("Please enter the message: "); //THE CLIENT MUST WRITE A COMMAND
fgets(buffer, 256, stdin); //apo stdin sto buffer
n = write(sockfd, buffer, strlen(buffer)); //apo buffer sto socket
if(n < 0 ) {
error("ERROR writing to socket");
}
bzero(buffer, 256);
if ( recv(sockfd, buffer, 256, 0) < 0) {
printf("Server closed connection\n");
}
printf("%s\n", buffer);
}
return 0;
}
服务器.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
void parse(char *vector_args[20], char *buffer){
buffer[strcspn(buffer, "\n")] =0;
int i=0;
char * pch;
pch = strtok (buffer," ");
while (pch != NULL )
{
vector_args[i]=pch;
printf (" %s\n",pch);
pch = strtok (NULL, " ");
i++;
}
vector_args[i]=NULL;
int k=0;
for(k=0; k<=i; k++) {
printf("vector %d = %s \n",k,vector_args[k]);
}
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
char str[INET_ADDRSTRLEN];
char *vector_args[20];
int status;
char *fd[2];
if (argc < 2)
{
fprintf(stderr, "No port provided\n");
exit(1);
}
unlink("sockfd"); //remove any old socket
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_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");
int l = listen(sockfd, 5);
if (l < 0)
{
error("listen failed!");
}
clilen = sizeof(cli_addr);
printf( "Server waiting for a connection...\n " );
while(1) {
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, "Connected!\nThe client address is :%s\n", str);
//fork new process
int pid = fork();
if (pid == -1 ) {
error("ERROR in new process creation");
close(newsockfd);
continue;
}else if( pid != 0){
//parent process
close(newsockfd);//h edw h prin to continue
printf( " I am parent process %d\n " ,getpid()); //BGALE
if (wait(&status)== -1) /* Wait for child*/
{
perror( " wait " );
}
check_child_exit(status);
continue;
}else if (pid == 0) {
//child process
close(sockfd);
bzero(buffer, 256);
while(1) {
n = read(newsockfd, buffer, 255); //apo socket ston buffer
if (n < 0 )
error("ERROR reading from socket");
printf("Here is the message: %s\n", buffer);
n = write(newsockfd, "I got your message", 18);
bzero(buffer, 256);
close(1); //close stdin
dup2( newsockfd, 1);
close(0); //close stdout
dup2( newsockfd, 0);
parse(vector_args,buffer);
execvp(vector_args[0] , vector_args );
perror( " execvp " );
exit(EXIT_FAILURE);
bzero(buffer, 256);
}
close(newsockfd);
break;
}
}
}
您知道如何更改代码才能正常工作吗?
最佳答案
循环
while (1) {
....
execvp(....);
}
有效执行一次。原因是成功的 execvp
用任何 vector_args
请求替换代码,并且执行的进程在完成后退出。
如果我正确理解你的目标(每个连接一个进程,在循环中执行外部命令),你还需要一个分支,沿着
while (1) {
....
if ((pid = fork()) == 0) {
execvp(....);
} else if (pid > 0) {
waitpid(....);
} else {
handle_error();
}
}
关于客户端与服务器通信,执行命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54425740/