Remote Commander
ตัวอย่างโปรแกรมประยุกต์เพื่อใช้ในการส่งชุดคำสั่งระยะไกล เพื่อให้ไปประมวลผลคำสั่งที่เครื่องปลายทาง (server.c) แล้วส่งผลลัพธ์กลับมายังเครื่องที่สั่งการ (client.c) โดยใช้เทคนิคการสื่อสารด้วย socket ดังตัวอย่างข้างล่างนี้
โปรแกรม server.c
// server.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define PORT 8080
// Function to execute shell commands and return results.
void execute_command(char* command, char* result, int resultBufferSize) {
FILE* pipe = popen(command, "r");
if (!pipe) {
strcpy(result, "popen() failed!");
return;
}
char buffer[128];
int totalBytesRead = 0;
while (fgets(buffer, sizeof(buffer), pipe) != NULL) {
int bytesRead = strlen(buffer);
// Make sure we don't exceed the buffer size
if (totalBytesRead + bytesRead >= resultBufferSize) {
break;
}
strcat(result, buffer); // Append the new data to the total result
totalBytesRead += bytesRead;
}
if (pclose(pipe) != 0) {
// Handle errors reported by pclose(),
// perhaps appending a message to the result
}
}
int main(int argc, char const *argv[]) {
int server_fd, new_socket;
struct sockaddr_in address;
int opt = 1;
int addrlen = sizeof(address);
char buffer[1024] = {0};
char result[1024];
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the PORT 8080
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
// Binding socket to the PORT 8080
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("bind failed");
exit(EXIT_FAILURE);
}
// Display the server's IP and listening port
char host[256];
char *IP;
struct hostent *host_entry;
gethostname(host, sizeof(host));
host_entry = gethostbyname(host);
IP = inet_ntoa(*((struct in_addr*) host_entry->h_addr_list[0]));
if (listen(server_fd, 3) < 0) {
perror("listen");
exit(EXIT_FAILURE);
}
printf("Server is running at IP: %s on Port: %d\n", IP, PORT);
// Main loop to keep server running and accepting new connections
while (1) {
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
printf("Connection established...\n");
// Communication loop with the connected client
while (1) {
memset(buffer, 0, BUFFER_SIZE); // Clear the buffer
int read_size = read(new_socket, buffer, BUFFER_SIZE);
if (read_size > 0) {
printf("Received command: %s\n", buffer);
// Special case: close connection if client sends "exit"
if (strcmp(buffer, "exit") == 0) {
printf("Closing connection...\n");
close(new_socket);
break; // Break out of the inner loop to start accepting new connections
}
// Execute the command
execute_command(buffer, result, sizeof(result));
// printf("Command result: %s\n", result);
send(new_socket, result, strlen(result), 0);
printf("Result sent back to client\n");
memset(result, 0, BUFFER_SIZE); // Clear the result buffer
} else {
printf("Client disconnected or read error...\n");
close(new_socket);
break; // Break out of the inner loop to start accepting new connections
}
}
}
return 0;
}เพื่อให้โปรแกรมสั่งการ (client.c) ทำตัวเองเหมือน Shell terminal ในการรันคำสั่งจากผู้ใช้ โดยใช้ตามมาตราฐาน VT100/ANSI Terminal จึงต้องมีการติดตั้ง library ที่ชื่อว่า libreadline-dev ก่อน เพื่อเรียกใช้ในโปรแกรม client.c ได้ดังนี้
ทำการคอมไพล์โปรแกรมทั้งสอง โดยสร้างหน้าต่าง terminal 2 หน้าต่าง ดังนี้
Last updated
Was this helpful?