我为客户端和服务器编写了一个程序,它会向服务器发送一条命令,在服务器上执行用户提到的次数,并每次传输发送 64 字节的内容,直到所有数据发送到客户端并打印。问题是它没有按照我的预期工作,我检查了错误,但无法解决问题。请帮助我,我将附上客户端和服务器程序。
客户:
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef struct sockaddr_in sock;
typedef struct sockaddr sck;
int main()
{
char cmd[10],rcv[65];
int tm,end,ack = 1;
printf("Enter any standard LS command: ");
scanf("%s",cmd);
printf("Enter no.of times to be executed: ");
scanf("%d",&tm);
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
sock addr;
int len = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(5000);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
sendto(sockfd,cmd,sizeof(cmd),0,(sck *)&addr,len);
sendto(sockfd,&tm,sizeof(int),0,(sck *)&addr,len);
while(end)
{
int sz = recvfrom(sockfd,rcv,sizeof(rcv),0,(sck *)&addr,&len);
printf("%s\n",rcv);
if(sz == 64)
sendto(sockfd,&ack,sizeof(int),0,(sck *)&addr,len);
else
{
ack = 0;
sendto(sockfd,&ack,sizeof(int),0,(sck *)&addr,len);
}
recvfrom(sockfd,&end,sizeof(int),0,(sck *)&addr,&len);
}
close(sockfd);
}
服务器:
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef struct sockaddr_in sock;
typedef struct sockaddr sck;
int main()
{
char cmd[10],snd[65],ch;
int tm,cn = 0,end = 1, ack;
int sockfd = socket(AF_INET,SOCK_DGRAM,0);
sock addr;
int len = sizeof(addr);
addr.sin_family = AF_INET;
addr.sin_port = htons(5000);
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
bind(sockfd,(sck *)&addr,sizeof(addr));
recvfrom(sockfd,cmd,sizeof(cmd),0,(sck *)&addr,&len);
recvfrom(sockfd,&tm,sizeof(int),0,(sck *)&addr,&len);
int fd = open("op.txt",O_CREAT | O_WRONLY | O_TRUNC,0644);
int bc = dup(1);
dup2(fd,1);
for(int i = 1;i <= tm;i++)
system(cmd);
close(fd);
dup2(bc,1);
fd = open("op.txt",O_RDONLY);
while(read(fd,&ch,1))
{
if(cn < 64)
snd[cn] = ch;
else
{
snd[cn] = '\0';
sendto(sockfd,snd,sizeof(snd),0,(sck *)&addr,len);
recvfrom(sockfd,&ack,sizeof(ack),0,(sck *)&addr,&len);
if(!ack)
{
end = 0;
sendto(sockfd,&end,sizeof(int),0,(sck *)&addr,len);
break;
}
else
sendto(sockfd,&end,sizeof(int),0,(sck *)&addr,len);
cn = 0;
}
cn++;
}
close(fd);
close(sockfd);
}
我谨慎地假设你问题的初衷是这样的
ls -al .
和重复计数(服务器执行客户端给定命令的次数),例如3
。ls -al .
、3
)op.txt
(至少你的代码似乎可以使用此文件)。op.txt
的内容发送回客户端。基于这个假设,我又重写了程序。
// server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <fcntl.h>
#define SERVER_PORT 5000
#define BUFFER_SIZE 1024
#define OUTPUT_FILE "op.txt"
#define END_MESSAGE "END"
// Function to send data to the client
void send_data(int sockfd, struct sockaddr_in *client_addr, socklen_t addr_len, const char *data, size_t data_len) {
ssize_t sent_bytes = sendto(sockfd, data, data_len, 0, (struct sockaddr *)client_addr, addr_len);
if (sent_bytes == -1) {
perror("sendto failed");
}
}
int main() {
int sockfd;
struct sockaddr_in server_addr, client_addr;
socklen_t addr_len = sizeof(client_addr);
char buffer[BUFFER_SIZE];
char command[256];
int repetition;
// Create UDP socket
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// Bind the socket to server address
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = INADDR_ANY; // Listen on all interfaces
if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {
perror("bind failed");
close(sockfd);
exit(EXIT_FAILURE);
}
printf("Server is up and listening on port %d...\n", SERVER_PORT);
// Receive command from client
ssize_t bytes_received = recvfrom(sockfd, buffer, BUFFER_SIZE - 1, 0, (struct sockaddr *)&client_addr, &addr_len);
if (bytes_received == -1) {
perror("recvfrom failed for command");
close(sockfd);
exit(EXIT_FAILURE);
}
buffer[bytes_received] = '\0';
strncpy(command, buffer, sizeof(command) - 1);
command[sizeof(command) - 1] = '\0'; // Ensure null-termination
printf("Received command: %s\n", command);
// Receive repetition count from client
bytes_received = recvfrom(sockfd, &repetition, sizeof(repetition), 0, (struct sockaddr *)&client_addr, &addr_len);
if (bytes_received == -1) {
perror("recvfrom failed for repetition count");
close(sockfd);
exit(EXIT_FAILURE);
}
printf("Repetition count: %d\n", repetition);
// Execute the command the specified number of times and capture the output
FILE *fp = fopen(OUTPUT_FILE, "w");
if (fp == NULL) {
perror("Failed to open output file");
close(sockfd);
exit(EXIT_FAILURE);
}
// Redirect stdout to the file
int stdout_copy = dup(STDOUT_FILENO);
if (stdout_copy == -1) {
perror("dup failed");
fclose(fp);
close(sockfd);
exit(EXIT_FAILURE);
}
if (dup2(fileno(fp), STDOUT_FILENO) == -1) {
perror("dup2 failed");
fclose(fp);
close(sockfd);
exit(EXIT_FAILURE);
}
// Execute the command multiple times
for (int i = 0; i < repetition; i++) {
printf("Execution %d:\n", i + 1);
if (system(command) == -1) {
fprintf(stderr, "Failed to execute command: %s\n", command);
}
printf("\n"); // Add spacing between executions
}
// Restore stdout
if (dup2(stdout_copy, STDOUT_FILENO) == -1) {
perror("dup2 restore failed");
}
close(stdout_copy);
fclose(fp);
// Open the output file for reading
fp = fopen(OUTPUT_FILE, "r");
if (fp == NULL) {
perror("Failed to open output file for reading");
close(sockfd);
exit(EXIT_FAILURE);
}
printf("Sending output to client...\n");
// Send the file content in chunks
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
send_data(sockfd, &client_addr, addr_len, buffer, strlen(buffer));
usleep(10000);
}
// Send the END message to indicate completion
send_data(sockfd, &client_addr, addr_len, END_MESSAGE, strlen(END_MESSAGE) + 1);
printf("Output sent successfully.\n");
fclose(fp);
close(sockfd);
return 0;
}
// client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define SERVER_PORT 5000
#define SERVER_IP "127.0.0.1"
#define BUFFER_SIZE 1024
#define END_MESSAGE "END"
// Function to send data to the server
void send_data(int sockfd, struct sockaddr_in *server_addr, socklen_t addr_len, const char *data, size_t data_len) {
ssize_t sent_bytes = sendto(sockfd, data, data_len, 0, (struct sockaddr *)server_addr, addr_len);
if (sent_bytes == -1) {
perror("sendto failed");
exit(EXIT_FAILURE);
}
}
// Function to receive data from the server
ssize_t receive_data(int sockfd, char *buffer, size_t buffer_size, struct sockaddr_in *server_addr, socklen_t *addr_len) {
ssize_t received_bytes = recvfrom(sockfd, buffer, buffer_size - 1, 0, (struct sockaddr *)server_addr, addr_len);
if (received_bytes == -1) {
perror("recvfrom failed");
exit(EXIT_FAILURE);
}
buffer[received_bytes] = '\0'; // Null-terminate the received data
return received_bytes;
}
int main() {
char command[256];
int repetition;
char buffer[BUFFER_SIZE];
struct sockaddr_in server_addr;
socklen_t addr_len = sizeof(server_addr);
// Get user input
printf("Enter the command to execute (e.g., ls -al .): ");
fgets(command, sizeof(command), stdin);
command[strcspn(command, "\n")] = '\0'; // Remove newline character
printf("Enter the number of times to execute the command: ");
if (scanf("%d", &repetition) != 1 || repetition < 1) {
fprintf(stderr, "Invalid repetition count.\n");
exit(EXIT_FAILURE);
}
// Create UDP socket
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
// Configure server address
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
if(inet_aton(SERVER_IP, &server_addr.sin_addr) == 0){
fprintf(stderr, "Invalid server IP address.\n");
close(sockfd);
exit(EXIT_FAILURE);
}
// Send command length and command
send_data(sockfd, &server_addr, addr_len, command, strlen(command) + 1);
// Send repetition count
send_data(sockfd, &server_addr, addr_len, (char *)&repetition, sizeof(repetition));
printf("\n--- Receiving Output ---\n");
// Receive data until "END" message is received
while (1) {
ssize_t bytes_received = receive_data(sockfd, buffer, BUFFER_SIZE, &server_addr, &addr_len);
if (strcmp(buffer, END_MESSAGE) == 0) {
printf("\n--- End of Output ---\n");
break;
}
printf("%s", buffer);
}
close(sockfd);
return 0;
}
执行示例如下
我希望这就是你当时想要的......