C++ UNIX 帮助 - 简单的 TCP 服务器套接字连接
C++ UNIX Help - simple TCP server socket connection
我是一名学生,正在编写 C++ 代码,使用 UNIX 系统调用来执行来自终端的简单服务器 <-> 客户端请求。用户(我)在终端输入两个程序(服务器和客户端)建立连接的端口,目的是让服务器将客户端程序输入的内容发送回客户端。
即:
1 号航站楼:
./服务器 9000
2 号航站楼:
./client localhost 9000 ~
将显示主页中所有目录和文件的列表。
或者
终端 2:./client localhost 9000 test.txt
将从 test.txt 文件中读取内容并将其写入客户的终端。
截至目前,只有文件夹可用。每当我尝试使用文件时,它都会打印一个空行。这是我的流程功能代码:
void processClientRequest(int connSock)
{
int received;
char path[1024], buffer[1024];
// Read from the client
if((received = read(connSock, path, sizeof(path))) < 0)
{ perror("receive"); exit(EXIT_FAILURE); }
// Check if it is a directory or a file
struct stat s;
if(stat(path,&s) == 0 )
{
// It is a directory
if(s.st_mode & S_IFDIR)
{
DIR *dirp = opendir(path);
if (dirp == 0)
{
// Tell client they gave the inappropriate input
// Duplicate socket descriptor into error output
// Then print it to client's end with perror to
// Give more in-depth details of the error to user
close(2);
dup(connSock);
perror(path);
exit(EXIT_SUCCESS);
}
struct dirent *dirEntry;
while((dirEntry = readdir(dirp)) != NULL)
{
// If statement to hides all files/folders that start with a dot
// Which are hidden files/folders
if(dirEntry->d_name[0] != '.')
{
strcpy(buffer, dirEntry->d_name);
strcat(buffer, "\n");
if(write(connSock, buffer, strlen(buffer)) < 0)
{ perror("write"); exit(EXIT_FAILURE); }
}
}
closedir(dirp);
close(connSock);
exit(EXIT_SUCCESS);
}
// It is a file
else if(s.st_mode & S_IFREG)
{
int fd = open(path, O_RDONLY);
if(fd < 0) { perror("open"); exit(EXIT_FAILURE); }
read(fd, buffer, strlen(buffer));
strcat(buffer, "\n");
if(write(connSock, buffer, strlen(buffer)) < 0)
{ perror("write"); exit(EXIT_FAILURE); }
close(fd);
}
// Not a file or directory
else
{
cout << "It is neither a file nor directory!" << endl;
exit(EXIT_FAILURE);
}
}
else
{
// Same explanation as line 95 - 98
close(2);
dup(connSock);
perror("stat");
exit(EXIT_SUCCESS);
}
close(connSock);
exit(EXIT_SUCCESS);
}
作为一个附带问题,在执行该过程之前如何将它变成 accept/recognize 代码字以及双引号?截至目前,我只能使用 ./client ... pathname/"name with spaces" ;如果我使用 ./client ... "pathname/name with spaces" 它会显示 stat: no such file or directory 错误。
例如:
./client localhost 4000 "GET pathname/filename"
你的问题在这里:
else if(s.st_mode & S_IFREG)
{
int fd = open(path, O_RDONLY);
if(fd < 0) { perror("open"); exit(EXIT_FAILURE); }
read(fd, buffer, strlen(buffer)); << Change strlen(buffer)
strcat(buffer, "\n");
if(write(connSock, buffer, strlen(buffer)) < 0)
{ perror("write"); exit(EXIT_FAILURE); }
close(fd);
}
strlen(buffer)
可以是任何值,因为您正在将缓冲区初始化为 1024 字节。内存区域可能被填满了零。 strlen(buffer)
将返回 0,因为第一个字符是空字节。没有任何内容被写入缓冲区,因为 read
将最终写入零字节。
我是一名学生,正在编写 C++ 代码,使用 UNIX 系统调用来执行来自终端的简单服务器 <-> 客户端请求。用户(我)在终端输入两个程序(服务器和客户端)建立连接的端口,目的是让服务器将客户端程序输入的内容发送回客户端。
即:
1 号航站楼: ./服务器 9000
2 号航站楼: ./client localhost 9000 ~
将显示主页中所有目录和文件的列表。
或者 终端 2:./client localhost 9000 test.txt
将从 test.txt 文件中读取内容并将其写入客户的终端。
截至目前,只有文件夹可用。每当我尝试使用文件时,它都会打印一个空行。这是我的流程功能代码:
void processClientRequest(int connSock)
{
int received;
char path[1024], buffer[1024];
// Read from the client
if((received = read(connSock, path, sizeof(path))) < 0)
{ perror("receive"); exit(EXIT_FAILURE); }
// Check if it is a directory or a file
struct stat s;
if(stat(path,&s) == 0 )
{
// It is a directory
if(s.st_mode & S_IFDIR)
{
DIR *dirp = opendir(path);
if (dirp == 0)
{
// Tell client they gave the inappropriate input
// Duplicate socket descriptor into error output
// Then print it to client's end with perror to
// Give more in-depth details of the error to user
close(2);
dup(connSock);
perror(path);
exit(EXIT_SUCCESS);
}
struct dirent *dirEntry;
while((dirEntry = readdir(dirp)) != NULL)
{
// If statement to hides all files/folders that start with a dot
// Which are hidden files/folders
if(dirEntry->d_name[0] != '.')
{
strcpy(buffer, dirEntry->d_name);
strcat(buffer, "\n");
if(write(connSock, buffer, strlen(buffer)) < 0)
{ perror("write"); exit(EXIT_FAILURE); }
}
}
closedir(dirp);
close(connSock);
exit(EXIT_SUCCESS);
}
// It is a file
else if(s.st_mode & S_IFREG)
{
int fd = open(path, O_RDONLY);
if(fd < 0) { perror("open"); exit(EXIT_FAILURE); }
read(fd, buffer, strlen(buffer));
strcat(buffer, "\n");
if(write(connSock, buffer, strlen(buffer)) < 0)
{ perror("write"); exit(EXIT_FAILURE); }
close(fd);
}
// Not a file or directory
else
{
cout << "It is neither a file nor directory!" << endl;
exit(EXIT_FAILURE);
}
}
else
{
// Same explanation as line 95 - 98
close(2);
dup(connSock);
perror("stat");
exit(EXIT_SUCCESS);
}
close(connSock);
exit(EXIT_SUCCESS);
}
作为一个附带问题,在执行该过程之前如何将它变成 accept/recognize 代码字以及双引号?截至目前,我只能使用 ./client ... pathname/"name with spaces" ;如果我使用 ./client ... "pathname/name with spaces" 它会显示 stat: no such file or directory 错误。 例如:
./client localhost 4000 "GET pathname/filename"
你的问题在这里:
else if(s.st_mode & S_IFREG)
{
int fd = open(path, O_RDONLY);
if(fd < 0) { perror("open"); exit(EXIT_FAILURE); }
read(fd, buffer, strlen(buffer)); << Change strlen(buffer)
strcat(buffer, "\n");
if(write(connSock, buffer, strlen(buffer)) < 0)
{ perror("write"); exit(EXIT_FAILURE); }
close(fd);
}
strlen(buffer)
可以是任何值,因为您正在将缓冲区初始化为 1024 字节。内存区域可能被填满了零。 strlen(buffer)
将返回 0,因为第一个字符是空字节。没有任何内容被写入缓冲区,因为 read
将最终写入零字节。