C 中涉及套接字和客户端-服务器通信的程序问题
Issue with program involving sockets and client-server communication in C
我正在用 C 开发一个涉及客户端-服务器连接和双方通信的程序。
该程序涉及客户端向服务器端发送信件,服务器端收到信件。服务器然后在当前文件目录(在 linux 中)搜索以该字母开头的文件,并向客户端发送文件的字节数和文件的文本。
整个程序很长,对于作业,讲师已经做了很多代码,例如设置套接字和为操作的客户端创建整个程序。
对于服务器端,我必须为以下代码编写代码:
- 从传递的内存中获取文件描述符并转换它
-收到客户来信
-正在尝试打开当前目录
-遍历目录寻找以字母
开头的文件
-尝试打开文件并以网络字节序向客户端发送文件大小和文件字节数
-完成后关闭文件和目录
-错误检查:目录打不开,文件打不开,或者没有找到匹配的文件,都有错误检查语句
以下是我的注释代码
void* handleClient (void* vPtr
)
{
// I. Application validity check:
int fd = *((int *) vPtr);
//casting vPtr to an int//
free(vPtr);
// II. Handle the client:
char buffer[BUFFER_LEN+1];
read(fd, buffer, BUFFER_LEN+1);
//read the letter into a buffer//
const char* dirNamePtr = ".";
DIR* dirPtr = opendir(dirNamePtr);
// Open the current directory
if (dirPtr == NULL)
{
int toSend = htonl(CANT_READ_DIR_CODE);
write(fd,&toSend,sizeof(toSend));
printf("Cannot read directory\n");
return(NULL);
}
// If current directory cannot be opened, it sends a error message in network // endian to the client
struct dirent* entryPtr;
char path[BUFFER_LEN];
struct stat statBuffer;
//implements struct dirent to get info on the directory
//iterates through the directory
while ((entryPtr=readdir(dirPtr)) != NULL)
{
stat(entryPtr->d_name, &statBuffer);
//puts in metaddata of the current directory into statbuffer
if (!S_ISREG(statBuffer.st_mode))
continue;
//if the entry is not a file, continue
// if the first letter of the file is not the character received from the //client, send an error mesage
if(entryPtr->d_name[0]!=buffer[0]) {
int toSend2 = htonl(NO_MATCH_CODE);
write(fd,&toSend2,sizeof(toSend2));
printf("No matching file\n");
return(NULL);
}
int ab;
int numRead;
int numBytes;
char buffer[BUFFER_LEN];
//open the file and send bytes of file and file size to client
if (entryPtr->d_name[0]==buffer[0] &(S_ISREG(statBuffer.st_mode)))
{
ab=open(entryPtr->d_name,O_RDONLY,0660);
if(ab<0) {
int toSend3 = htonl(CANT_READ_FILE_CODE);
write(fd,&toSend3, sizeof(toSend3));
printf("Cannot read <filename>\n");
return(NULL);
}
numBytes=htonl(statBuffer.st_size);
write(fd, &numBytes, sizeof(numBytes));
printf("Sending %s, %d bytes\n",entryPtr >d_name,statBuffer.st_size);
while((numBytes=read(ab,buffer,BUFFER_LEN))>0)
{
printf("We read %d bytes\n", numBytes);
write(fd, buffer, numBytes);
}
//close the fiel
close(ab);
}
break;
//leave the loop
}
// III. Finished:
//
closedir(dirPtr);
return(NULL);
}
我的代码可以编译,但当我尝试 运行 时没有将文件发送给客户端。我尝试了几个不同的字母,但对其中任何一个都不起作用。我不太清楚是什么问题导致我很难改正错误。
我不是要答案或任何东西,只是帮助看看我错在哪里。感谢您的帮助。
您关于何时发送与何时发送 no-file 状态的逻辑似乎有误。我认为它应该是这样的(公平的警告,我没有测试这个,甚至没有在基本语法检查之外编译它,但你应该明白这个想法):
void* handleClient(void* vPtr)
{
// I. Application validity check:
int fd = *((int *) vPtr);
free(vPtr);
// II. Handle the client:
char buffer[BUFFER_LEN+1];
read(fd, buffer, BUFFER_LEN+1);
//read the letter into a buffer//
const char* dirNamePtr = ".";
DIR* dirPtr = opendir(dirNamePtr);
// Open the current directory
if (dirPtr == NULL)
{
int toSend = htonl(CANT_READ_DIR_CODE);
write(fd,&toSend,sizeof(toSend));
printf("Cannot read directory\n");
return(NULL);
}
struct dirent* entryPtr;
char path[BUFFER_LEN];
struct stat statBuffer;
//implements struct dirent to get info on the directory
//iterates through the directory
while ((entryPtr=readdir(dirPtr)) != NULL)
{
stat(entryPtr->d_name, &statBuffer);
//puts in metaddata of the current directory into statbuffer
// if this isn't a regular file OR the first char doesn't match...
if (!S_ISREG(statBuffer.st_mode) || entryPtr->d_name[0]!=buffer[0])
continue;
int ab;
int numRead;
int numBytes;
char buffer[BUFFER_LEN];
//open the file and send bytes of file and file size to client
ab = open(entryPtr->d_name,O_RDONLY,0660);
if(ab<0) {
int toSend3 = htonl(CANT_READ_FILE_CODE);
write(fd,&toSend3, sizeof(toSend3));
printf("Cannot read <filename>\n");
closedir(dirPtr);
return(NULL);
}
numBytes=htonl(statBuffer.st_size);
write(fd, &numBytes, sizeof(numBytes));
printf("Sending %s, %d bytes\n",entryPtr >d_name,statBuffer.st_size);
while((numBytes=read(ab,buffer,BUFFER_LEN))>0)
{
printf("We read %d bytes\n", numBytes);
write(fd, buffer, numBytes);
}
//close the file and leave
close(ab);
break;
}
// if this is NULL it means we dind't send anything. we break the loop
// when a file to send it discovered.
if (entryPtr == NULL)
{
printf("No matching file\n");
int toSend2 = htonl(NO_MATCH_CODE);
write(fd, &toSend2, sizeof(toSend2));
}
// III. Finished:
closedir(dirPtr);
return(NULL);
}
我正在用 C 开发一个涉及客户端-服务器连接和双方通信的程序。
该程序涉及客户端向服务器端发送信件,服务器端收到信件。服务器然后在当前文件目录(在 linux 中)搜索以该字母开头的文件,并向客户端发送文件的字节数和文件的文本。
整个程序很长,对于作业,讲师已经做了很多代码,例如设置套接字和为操作的客户端创建整个程序。
对于服务器端,我必须为以下代码编写代码:
- 从传递的内存中获取文件描述符并转换它
-收到客户来信
-正在尝试打开当前目录
-遍历目录寻找以字母
开头的文件-尝试打开文件并以网络字节序向客户端发送文件大小和文件字节数
-完成后关闭文件和目录
-错误检查:目录打不开,文件打不开,或者没有找到匹配的文件,都有错误检查语句
以下是我的注释代码
void* handleClient (void* vPtr
)
{
// I. Application validity check:
int fd = *((int *) vPtr);
//casting vPtr to an int//
free(vPtr);
// II. Handle the client:
char buffer[BUFFER_LEN+1];
read(fd, buffer, BUFFER_LEN+1);
//read the letter into a buffer//
const char* dirNamePtr = ".";
DIR* dirPtr = opendir(dirNamePtr);
// Open the current directory
if (dirPtr == NULL)
{
int toSend = htonl(CANT_READ_DIR_CODE);
write(fd,&toSend,sizeof(toSend));
printf("Cannot read directory\n");
return(NULL);
}
// If current directory cannot be opened, it sends a error message in network // endian to the client
struct dirent* entryPtr;
char path[BUFFER_LEN];
struct stat statBuffer;
//implements struct dirent to get info on the directory
//iterates through the directory
while ((entryPtr=readdir(dirPtr)) != NULL)
{
stat(entryPtr->d_name, &statBuffer);
//puts in metaddata of the current directory into statbuffer
if (!S_ISREG(statBuffer.st_mode))
continue;
//if the entry is not a file, continue
// if the first letter of the file is not the character received from the //client, send an error mesage
if(entryPtr->d_name[0]!=buffer[0]) {
int toSend2 = htonl(NO_MATCH_CODE);
write(fd,&toSend2,sizeof(toSend2));
printf("No matching file\n");
return(NULL);
}
int ab;
int numRead;
int numBytes;
char buffer[BUFFER_LEN];
//open the file and send bytes of file and file size to client
if (entryPtr->d_name[0]==buffer[0] &(S_ISREG(statBuffer.st_mode)))
{
ab=open(entryPtr->d_name,O_RDONLY,0660);
if(ab<0) {
int toSend3 = htonl(CANT_READ_FILE_CODE);
write(fd,&toSend3, sizeof(toSend3));
printf("Cannot read <filename>\n");
return(NULL);
}
numBytes=htonl(statBuffer.st_size);
write(fd, &numBytes, sizeof(numBytes));
printf("Sending %s, %d bytes\n",entryPtr >d_name,statBuffer.st_size);
while((numBytes=read(ab,buffer,BUFFER_LEN))>0)
{
printf("We read %d bytes\n", numBytes);
write(fd, buffer, numBytes);
}
//close the fiel
close(ab);
}
break;
//leave the loop
}
// III. Finished:
//
closedir(dirPtr);
return(NULL);
}
我的代码可以编译,但当我尝试 运行 时没有将文件发送给客户端。我尝试了几个不同的字母,但对其中任何一个都不起作用。我不太清楚是什么问题导致我很难改正错误。
我不是要答案或任何东西,只是帮助看看我错在哪里。感谢您的帮助。
您关于何时发送与何时发送 no-file 状态的逻辑似乎有误。我认为它应该是这样的(公平的警告,我没有测试这个,甚至没有在基本语法检查之外编译它,但你应该明白这个想法):
void* handleClient(void* vPtr)
{
// I. Application validity check:
int fd = *((int *) vPtr);
free(vPtr);
// II. Handle the client:
char buffer[BUFFER_LEN+1];
read(fd, buffer, BUFFER_LEN+1);
//read the letter into a buffer//
const char* dirNamePtr = ".";
DIR* dirPtr = opendir(dirNamePtr);
// Open the current directory
if (dirPtr == NULL)
{
int toSend = htonl(CANT_READ_DIR_CODE);
write(fd,&toSend,sizeof(toSend));
printf("Cannot read directory\n");
return(NULL);
}
struct dirent* entryPtr;
char path[BUFFER_LEN];
struct stat statBuffer;
//implements struct dirent to get info on the directory
//iterates through the directory
while ((entryPtr=readdir(dirPtr)) != NULL)
{
stat(entryPtr->d_name, &statBuffer);
//puts in metaddata of the current directory into statbuffer
// if this isn't a regular file OR the first char doesn't match...
if (!S_ISREG(statBuffer.st_mode) || entryPtr->d_name[0]!=buffer[0])
continue;
int ab;
int numRead;
int numBytes;
char buffer[BUFFER_LEN];
//open the file and send bytes of file and file size to client
ab = open(entryPtr->d_name,O_RDONLY,0660);
if(ab<0) {
int toSend3 = htonl(CANT_READ_FILE_CODE);
write(fd,&toSend3, sizeof(toSend3));
printf("Cannot read <filename>\n");
closedir(dirPtr);
return(NULL);
}
numBytes=htonl(statBuffer.st_size);
write(fd, &numBytes, sizeof(numBytes));
printf("Sending %s, %d bytes\n",entryPtr >d_name,statBuffer.st_size);
while((numBytes=read(ab,buffer,BUFFER_LEN))>0)
{
printf("We read %d bytes\n", numBytes);
write(fd, buffer, numBytes);
}
//close the file and leave
close(ab);
break;
}
// if this is NULL it means we dind't send anything. we break the loop
// when a file to send it discovered.
if (entryPtr == NULL)
{
printf("No matching file\n");
int toSend2 = htonl(NO_MATCH_CODE);
write(fd, &toSend2, sizeof(toSend2));
}
// III. Finished:
closedir(dirPtr);
return(NULL);
}