我已经尝试了所有方法,以便让我的服务器类在从客户端获得“CLOSE”消息时关闭套接字,或者在获得"AUTOTEST"
消息时运行AutoTest()
,等等。但每一次,它不注册消息,我不知道为什么。为了保持简短,我让AutoTest()
函数只打印出一条消息,说它测试了它,因为主要的问题只是让消息注册。运行时的输出如下:
./PhotoLab_server: Preparing the server address...
./PhotoLab_server: Assigning the server name to the socket...
./PhotoLab_server: Listening on port 2004...
./PhotoLab_server: Accepted connection from client
./PhotoLab_server: Received message: AUTOTEST
./PhotoLab_server: Sending response: OK.
./PhotoLab_server: Received message: CLOSE
ST
./PhotoLab_server: Sending response: OK.
客户:
./PhotoLab_client: Using port 2004...
./PhotoLab_client: Creating a socket...
./PhotoLab_client: Preparing the server address...
./PhotoLab_client: Connecting to the server...
./PhotoLab_client: Sending a request AUTOTEST
./PhotoLab_client: Waiting for response...
./PhotoLab_client: Received response: OK.
./PhotoLab_client: Sending a request CLOSE
./PhotoLab_client: Waiting for response...
./PhotoLab_client: Received response: OK.
./PhotoLab_client: Sending a request
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
/*** global definitions ***/
#define SLEN 80 /* maximum length of file names */
#define MAX_PIXEL 255 /* maximum pixel intesity value */
/* test all functions */
int AutoTest(void);
/* Displays an error message to the command line */
void FatalError(const char *Program, const char *ErrorMsg);
/* Prints out the available command flags */
void PrintUsage();
int main(int argc, char *argv[]) {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
int port;
/* Parse command line arguments */
if (argc != 3 || strcmp(argv[1], "-p") != 0) {
FatalError(argv[0], "Usage: %s -p <port>\n");
}
port = atoi(argv[2]);
/* Validate the port number */
if (port < 2000) {
FatalError(argv[0], "Error: Port number must be greater than or equal to 2000\n");
}
printf("%s: Preparing the server address...\n", argv[0]);
/* Create a socket */
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
FatalError(argv[0], "Error creating socket\n");
}
printf("%s: Assigning the server name to the socket...\n", argv[0]);
/* Bind the socket to a specific IP address and port */
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(port);
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
FatalError(argv[0], "Error binding socket\n");
}
printf("%s: Listening on port %d...\n", argv[0], port);
/* Listen for incoming connections */
if (listen(server_fd, 3) < 0) {
FatalError(argv[0], "Error listening on socket\n");
}
/* Accept incoming connections and serve client requests */
while (1) {
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
FatalError(argv[0], "Error accepting client connection\n");
}
printf("%s: Accepted connection from client\n", argv[0]);
char buffer[256] = {0};
int valread = 0;
while ((valread = read(new_socket, buffer, 256)) > 0) {
printf("%s: Received message: %s", argv[0], buffer);
/* Check if the client sent a CLOSE request */
if (strcmp(buffer, "CLOSE") == 0) {
break;
}
/* Check if the client sent an AUTOTEST request */
else if (strcmp(buffer, "AUTOTEST") == 0) {
AutoTest();
const char *response = "Autotest completed";
send(new_socket, response, strlen(response), 0);
}
/* Handle other client requests */
else {
/* Handle the client request */
const char *response = "OK.";
send(new_socket, response, strlen(response), 0);
printf("%s: Sending response: %s\n", argv[0], response);
}
}
/* Close the client connection */
close(new_socket);
printf("%s: Closed connection with client\n", argv[0]);
/* Break out of the loop if a CLOSE request was received */
if (valread == 0 || strcmp(buffer, "CLOSE") == 0) {
printf("%s: Server exiting...\n", argv[0]);
break;
}
}
/* Close the server socket */
close(server_fd);
printf("%s: Server socket closed\n", argv[0]);
return 0;
}
/* test all functions */
int AutoTest(void) {
printf("tested");
return 1;
}
/* Displays an error message to the command line and exits the program */
void FatalError(const char *Program, const char *ErrorMsg) {
fprintf(stderr, "%s: %s\n", Program, ErrorMsg);
exit(EXIT_FAILURE);
}
/* Prints out the available command flags */
void PrintUsage() {
printf("Usage: PhotoLab_server -p <port_no>");
printf("Options:");
printf("-p Specify the server port number");
printf("-h Display this usage information");
}
客户类别:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
/* Displays an error message to the command line */
void FatalError(const char *Program, const char *ErrorMsg);
/* Sends a request to the specified socket */
int SendRequest(const int SocketFD, const char *ReqMsg);
/* Prints out the available command flags */
void PrintUsage();
int main(int argc, char *argv[]) {
int x;
char *server_ip;
int port_number = -1;
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("./PhotoLab_client: Error creating a socket...");
exit(1);
}
while (x < argc) {
/* the server ip address option */
if (strcmp(argv[x], "-ip") == 0) {
if (x < argc - 1) {
server_ip = argv[x+1];
} else {
printf("Missing argument for server IP address!\n");
return 5;
}
x += 2;
continue;
}
/* the port number option */
if (strcmp(argv[x], "-p") == 0) {
if (x < argc - 1) {
if (sscanf(argv[x+1], "%d", &port_number) == 1) {
x += 2;
continue;
} else {
printf("Invalid port number argument!\n");
return 5;
}
} else {
printf("Missing argument for port number!\n");
return 5;
}
}
/* the help option */
if (strcmp(argv[x], "-h") == 0) {
PrintUsage();
return 0;
}
/* the print option */
if (strcmp(argv[x], "-print") == 0) {
SendRequest(sockfd, "print");
return 0;
}
/* the autotest option */
if (strcmp(argv[x], "-autotest") == 0) {
SendRequest(sockfd, "AUTOTEST");
printf("autotest");
return 0;
}
x++;
}
if (server_ip == NULL || port_number == -1) {
printf("Missing required arguments!\n");
return 5;
}
printf("%s: Using port %d...\n", argv[0], port_number);
struct sockaddr_in serv_addr;
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = inet_addr(server_ip);
serv_addr.sin_port = htons(port_number);
printf("./PhotoLab_client: Creating a socket...\n");
printf("%s: Preparing the server address...\n", argv[0]);
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
perror("./PhotoLab_client: Error connecting to server...");
exit(1);
}
printf("%s: Connecting to the server...\n", argv[0]);
while (1) {
char input[100];
printf("%s: Sending a request ", argv[0]);
fgets(input, sizeof(input), stdin);
printf("%s: Waiting for response...\n", argv[0]);
SendRequest(sockfd, input);
char buffer[256] = {0};
int valread = read(sockfd, buffer, 256);
if (valread < 0) {
FatalError(argv[0], "Error receiving response from server");
exit(EXIT_FAILURE);
}
printf("%s: Received response: %s\n", argv[0], buffer);
}
return 0;
}
/* Displays an error message to the command line and exits the program */
void FatalError(const char *Program, const char *ErrorMsg) {
fprintf(stderr, "%s: %s\n", Program, ErrorMsg);
exit(EXIT_FAILURE);
}
/* Sends a request of what to do to the server */
int SendRequest(const int SocketFD, const char *ReqMsg) {
int n = send(SocketFD, ReqMsg, strlen(ReqMsg), 0);
if (n < 0) {
FatalError("SendRequest", "Failed to send request message.");
}
return n;
}
/* Print the usage information */
void PrintUsage() {
printf("-------------------------------------------------------------------------\n");
printf("Usage: PhotoLab_client -ip <server_ip> -p <port_no> -print -autotest\n");
printf("Options:\n");
printf("-ip Specify the server IP address\n");
printf("-p Specify the server port number\n");
printf("-print Send request to server to print supported DIP operations\n");
printf("-autotest Send request to server to run AutoTest functionality\n");
printf("-h Display this usage information\n");
printf("-------------------------------------------------------------------------\n");
}
我试着做一个函数来接收消息,并多次更改服务器/客户端的代码,只是为了让它注册消息,但我不能弄清楚为什么它不起作用。
1条答案
按热度按时间tv6aics11#
你需要在每次迭代中将缓冲区清零。看看你得到了什么:
我把
_
放在那里,这样它就只是一个字符,你可以看到比较,但这实际上是'\n'
或类似的东西,大概是从客户端发送的,所以strcmp
与"CLOSE"
的比较失败,因为它实际上是在比较"CLOSE\nST"
。也许这不是最有效的解决方案,但是您可以在每次迭代时将缓冲区清零,这样当消息从连接读入buffer
时,您总是会得到NUL终止。就像会做到的
正如在注解中所讨论的,您还需要考虑
fgets
添加到sent命令中的换行符。您可以在客户端、服务器端消除它,或者在strcmp
上考虑它。我的首选是在客户端usingstrcspan
上消除它: