发送简单消息在此程序中正常工作。
但是当我发送文件时它有一些问题。
还有另一个具有不同端口的套接字。
我做了另一个插座。
但是在绑定之后,当在服务器中调用listen方法时,
它停了下来。客户端发生连接错误。
请告诉我如何解决。
server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/_default_fcntl.h>
#include <sys/reent.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/unistd.h>
#include <dirent.h>
#include <sys/types.h>
#include <string.h>
#include <grp.h>
#include <dirent.h>
#include <pwd.h>
void error_handling(char *message);
void inst_list();
void inst_pwd();
void inst_cwd(char *target);
void inst_nlst();
void inst_dele();
void inst_mkd(char *target);
void inst_handling();
void inst_rmd(char *target);
void inst_retr(char *target);
char sendMsg[500] = "";
char workingPath[500]="/";
char homePath[500]="../../usr/ftp";
struct sockaddr_in clnt_adr;
int clnt_sock;
int main(int argc, char *argv[])
{
int serv_sock, data_sock, clnt_dataSock;
char message[BUF_SIZE];
int str_len, i;
char dataPort[] = "13000";
char welcomeMsg[30] = "Hello dataPort: ";
char dataConnectMsg[30] = "Data Connected!";
char method[10] = "";
char target[100] = "";
struct sockaddr_in serv_adr;
struct sockaddr_in data_adr;
struct sockaddr_in datcl_adr;
socklen_t clnt_adr_sz;//
socklen_t datcl_adr_sz;//
if(argc!=2) {
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
serv_sock=socket(PF_INET, SOCK_STREAM, 0);
data_sock = socket(PF_INET, SOCK_STREAM,0);
if(serv_sock==-1)
error_handling("socket() error");
if(data_sock == -1)
error_handling("Data socket() error");
memset(&serv_adr, 0, sizeof(serv_adr));
memset(&data_adr, 0, sizeof(data_adr));
serv_adr.sin_family=AF_INET;
serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_adr.sin_port=htons(atoi(argv[1]));
data_adr.sin_family = AF_INET;
data_adr.sin_addr.s_addr=htonl(INADDR_ANY);
data_adr.sin_port=htons(13230);
if(bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr))==-1)
error_handling("bind() error");
// if(bind(data_sock, (struct sockaddr*)&data_adr, sizeof(data_adr))==-1)
// error_handling("data bind() error");
if(listen(serv_sock, 5)==-1)
error_handling("listen() error");
// if(listen(data_sock, 5)==-1)
// error_handling("listen() error");
clnt_adr_sz=sizeof(clnt_adr);
// datcl_adr_sz=sizeof(datcl_adr);
for(i=0; i<5; i++)
{
clnt_sock=accept(serv_sock, (struct sockaddr*)&clnt_adr, &clnt_adr_sz);
if(clnt_sock==-1)
error_handling("accept() error");
else
printf("Connected client %d \n", i+1);
strcat(welcomeMsg , dataPort);
write(clnt_sock, welcomeMsg, strlen(welcomeMsg));
while((str_len=read(clnt_sock, message, BUF_SIZE))!=0)
{
message[str_len] = 0;
sscanf(message, "%s %s",method, target);
if(strcmp(method, "QUIT") == 0)
{
strcat(sendMsg, "Disconnected");
write(clnt_sock, sendMsg, strlen(sendMsg));
close(clnt_sock);
}
inst_handling(method, target);
write(clnt_sock, sendMsg, strlen(sendMsg));
memset(method, 0 , sizeof(char)*10);
memset(target, 0 , sizeof(char)*100);
memset(sendMsg, 0, sizeof(char)*500);
}
}
close(serv_sock);
return 0;
}
void inst_handling(char *method, char *target)
{
char cpyMessage[2048] = "";
char *token;
char protocol[100];
char host[200];
if(strcmp(method,"PWD") == 0)//작업 디렉토리 표시
inst_pwd();
else if(strcmp(method, "CWD") == 0)//작업 디렉토리 변경
inst_cwd(target);
else if(strcmp(method, "LIST") == 0)//원격지 파일 목록 보기
inst_list();
else if(strcmp(method, "NLST") == 0)///원격지 디렉토리 목록 보기
inst_nlst();
// else if(strcmp(method, "STOR") == 0)//원격지에 파일 저장
// inst_put(target,body);
else if(strcmp(method, "RETR") == 0)//원격지 파일 가져오기
inst_retr(target);
else if(strcmp(method, "DELE") == 0)//원격지 파일 삭제
inst_dele(target);
else if(strcmp(method, "MKD") == 0)//원격지 디렉토리 생성
inst_mkd(target);
else if(strcmp(method, "RMD") == 0)//원격지 디렉토리 제거
inst_rmd(target);
else
{
fputs("\n\n nowhere", stderr);
fputc('\n', stderr);
strcat(sendMsg, "Wrong Message");
}
}
void inst_pwd()
{
strcat(sendMsg,"Working Directory : ");
strcat(sendMsg, workingPath);
return;
}
void inst_cwd(char *target)
{
char fullPath[500] = "";
strcat(fullPath, homePath);
strcat(fullPath, target);
DIR *dir_ptr;
if ( ( dir_ptr = opendir( fullPath ) ) == NULL )
{
strcat(sendMsg, "Please enter correct path");
return;
}
memset(workingPath, 0 , sizeof(char)*500);
strcat(workingPath, target);
strcat(sendMsg, workingPath);
return;
}
void inst_list()
{
char fileList[200] = "";
char fullPath[500] = "";
strcat(fullPath, homePath);
strcat(fullPath, workingPath);
DIR *dir_ptr;
struct dirent *direntp; /* each entry */
struct stat info;
if ( ( dir_ptr = opendir( fullPath ) ) == NULL )
printf("ls1: cannot open %s\n", fullPath);
else
{
while ( ( direntp = readdir( dir_ptr ) ) != NULL )
{
if( stat(fullPath, &info) != -1 )
{
if(direntp->d_type != DT_DIR)
{
strcat(fileList, direntp->d_name);
strcat(fileList, "\n");
}
}
}
closedir(dir_ptr);
}
strcat(sendMsg,"File List : \n");
strcat(sendMsg,fileList);
return;
}
void inst_nlst()
{
char fileList[200] = "";
char fullPath[500] = "";
strcat(fullPath, homePath);
strcat(fullPath, workingPath);
DIR *dir_ptr;
struct dirent *direntp; /* each entry */
struct stat info;
if ( ( dir_ptr = opendir( fullPath ) ) == NULL )
printf("ls1: cannot open %s\n", fullPath);
else
{
while ( ( direntp = readdir( dir_ptr ) ) != NULL )
{
if( stat(fullPath, &info) != -1 )
{
if(direntp->d_type == DT_DIR)
{
strcat(fileList, direntp->d_name);
strcat(fileList, "\n");
}
}
}
closedir(dir_ptr);
}
strcat(sendMsg,"Directory List : \n");
strcat(sendMsg,fileList);
return;
}
void inst_dele(char *target)
{
char inst[1024] = "";
char path[1024] = "";
FILE *file = NULL;
mode_t file_mode;
struct stat file_info;
strcat(path, homePath);
strcat(path, target);
if(stat(path,&file_info) == -1)
{
strcat(sendMsg, "No such a file\n");
return;
}
file_mode = file_info.st_mode;
if (S_ISDIR(file_mode))
{//디렉토리 파일인 경우
strcat(sendMsg, "Error: The target is Directory\n");
return;
}
else if (S_ISREG(file_mode))
{//일반 파일인 경우
strcat(inst, "rm ");
strcat(inst, path);
if( system(inst) != -1 )
strcat(sendMsg, "The file is removed");
else
strcat(sendMsg, "Fail to remove the file\n");
return;
}
}
void inst_rmd(char *target)
{
char inst[1024] = "";
char path[1024] = "";
FILE *file = NULL;
mode_t file_mode;
struct stat file_info;
strcat(path, homePath);
strcat(path, target);
if(stat(path,&file_info) == -1)
{
strcat(sendMsg, "No such a file\n");
return;
}
file_mode = file_info.st_mode;
if (S_ISDIR(file_mode))//디렉토리 파일인 경우
{
int n=0;
struct dirent* d;
DIR* dir = opendir(path);
while((d = readdir(dir))!=NULL) n++;
if(n>2)
{
strcat(sendMsg, "The Directory is not empty\n");
return;
}
closedir(dir);
strcat(inst, "rmdir ");
strcat(inst, path);
if( system(inst) != -1 )
strcat(sendMsg, "The directory is removed");
else
strcat(sendMsg, "Fail to remove the Directory\n");
return;
}
else if (S_ISREG(file_mode))
{//일반 파일인 경우
strcat(sendMsg, "Error: The target is File\n");
return;
}
}
void inst_mkd(char *target)
{
char path[100] = "";
char inst[200] = "";
strcat(path, homePath);
strcat(path, target);//home path와 사용자가 입력한 path를 더해준다
strcat(inst, "mkdir -p ");//중간 폴더까지 모두 생성하도록 -p 옵션 사용
strcat(inst, path);
if(system(inst) != -1)
{
strcat(sendMsg, "The Directory is created");
}
return;
}
void inst_retr(char *target)
{
int read_cnt;
char buf[BUF_SIZE];
FILE * fp;
fp=fopen("../../usr/ftp/test.c", "rb");
while(1)
{
read_cnt=fread((void*)buf, 1, BUF_SIZE, fp);
if(read_cnt<BUF_SIZE)
{
write(clnt_sock, buf, read_cnt);
break;
}
write(clnt_sock, buf, BUF_SIZE);
}
puts("fin file data");
fclose(fp);
strcat(sendMsg,"END");
}
//int inst_delete(char *target)
//{
// char inst[1024] = "";
// char path[1024] = "../../usr/http";
// FILE *file = NULL;
// mode_t file_mode;
// struct stat file_info;
//
// strcat(path, target);
//
// if(stat(path,&file_info) == -1)
// {
// strcat(sendMessage, "HTTP/1.1 404 Not Found\n");
// return 0;
// }
//
// file_mode = file_info.st_mode;
// if (S_ISDIR(file_mode))
// {//디렉토리 파일인 경우
// strcat(inst, "rm -rf ");
// strcat(inst, path);
// system(inst);
// strcat(sendMessage, "HTTP/1.1 200 OK\n");
// return 0;
// }
// else if (S_ISREG(file_mode))
// {//일반 파일인 경우
// strcat(inst, "rm -f ");
// strcat(inst, "/usr/http");
// strcat(inst, path);
// system(inst);
// strcat(sendMessage, "HTTP/1.1 200 OK\n");
// return 0;
// }
//}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
文件传输模块
void inst_retr(char *target)
{
data_sock = socket(PF_INET, SOCK_STREAM,0);
if(data_sock == -1)
error_handling("Data socket() error");
memset(&data_adr, 0, sizeof(data_adr));
data_adr.sin_family = AF_INET;
data_adr.sin_addr.s_addr=htonl(INADDR_ANY);
data_adr.sin_port=htons(12501);
if(bind(data_sock, (struct sockaddr*)&data_adr, sizeof(data_adr))==-1)
error_handling("data bind() error");
else
error_handling("bind ok");
if(listen(data_sock, 5)==-1)
error_handling("listen() error");
datcl_adr_sz=sizeof(datcl_adr);
clnt_sock=accept(data_sock, (struct sockaddr*)&datcl_adr, &datcl_adr_sz);
if(clnt_sock==-1)
error_handling("accept() error");
else
printf("Connected data client \n");
int read_cnt;
char buf[BUF_SIZE];
char eof = EOF;
FILE * fp;
fp=fopen("../../usr/ftp/test.c", "rb");
while(1)
{
read_cnt=fread((void*)buf, 1, BUF_SIZE, fp);
if(read_cnt<BUF_SIZE)
{
write(clnt_sock, buf, read_cnt);
break;
}
write(clnt_sock, buf, BUF_SIZE);
puts("file data");
}
shutdown(clnt_sock, SHUT_WR);
puts("fin file data");
fclose(fp);
strcat(sendMsg,"END");
}
client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#define BUF_SIZE 1024
void error_handling(char *message);
void inst_retr();
int sock;
int main(int argc, char *argv[])
{
int datasock;
char message[BUF_SIZE];
char tmp[BUF_SIZE];
char dataMsg[BUF_SIZE];
char method[BUF_SIZE];
char target[BUF_SIZE];
int str_len;
struct sockaddr_in serv_adr, data_adr;
if(argc!=3) {
printf("Usage : %s <IP> <port>\n", argv[0]);
exit(1);
}
sock=socket(PF_INET, SOCK_STREAM, 0);
datasock=socket(PF_INET, SOCK_STREAM, 0);
if(sock==-1)
error_handling("socket() error");
if(datasock==-1)
error_handling("Data socket() error");
memset(&serv_adr, 0, sizeof(serv_adr));
memset(&data_adr, 0, sizeof(serv_adr));
serv_adr.sin_family=AF_INET;
serv_adr.sin_addr.s_addr=inet_addr(argv[1]);
serv_adr.sin_port=htons(atoi(argv[2]));
if(connect(sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr))==-1)
error_handling("connect() error!");
else
puts("Connected...........");
// data_adr.sin_family=AF_INET;
// data_adr.sin_addr.s_addr=htons(atoi(argv[1]));
// data_adr.sin_port=htons(13230);
//
// if(connect(datasock, (struct sockaddr*)&data_adr, sizeof(data_adr)) == -1)
// error_handling("data connect() error!");
// else
// puts("Connected.....data...");
str_len=read(sock, message, BUF_SIZE-1);
message[str_len]=0;
printf("%s\n", message);
while(1)
{
fputs("Input message(Q to quit): ", stdout);
fgets(message, BUF_SIZE, stdin);
message[strlen(message)-1] = 0;
if(strcmp(message,"QUIT") == 0)
break;
strcpy(tmp,message);
sscanf(tmp, "%s %s",method, target);
if(strcmp(method, "RETR") == 0)
{
write(sock, message, strlen(message));
inst_retr();
str_len=read(sock, message, BUF_SIZE-1);
message[str_len]=0;
printf("Message from server: %s\n", message);
memset(message, 0, sizeof(char)*BUF_SIZE);
memset(method, 0, sizeof(char)*BUF_SIZE);
memset(target, 0, sizeof(char)*BUF_SIZE);
continue;
}
// if(strcmp(message,"data") == 0)
// {
// write(sock, message, strlen(message));
//
//
// str_len=read(datasock, message, BUF_SIZE-1);
// message[str_len]=0;
// printf("Message from server: %s", message);
//
//
// }
write(sock, message, strlen(message));
str_len=read(sock, message, BUF_SIZE-1);
message[str_len]=0;
printf("Message from server: %s\n", message);
memset(message, 0, sizeof(char)*BUF_SIZE);
memset(method, 0, sizeof(char)*BUF_SIZE);
memset(target, 0, sizeof(char)*BUF_SIZE);
}
close(sock);
return 0;
}
void inst_retr()
{
char buf[BUF_SIZE];
int read_cnt;
FILE *fp;
fp=fopen("../../usr/ftp/receive.dat", "wb");
while((read_cnt=read(sock, buf, BUF_SIZE ))!=0)
fwrite((void*)buf, 1, read_cnt, fp);
puts("Received file data");
fclose(fp);
return;
}
void error_handling(char *message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
文件接收模块
void inst_retr()
{
datasock=socket(PF_INET, SOCK_STREAM, 0);
if(datasock==-1)
error_handling("Data socket() error");
if(connect(datasock, (struct sockaddr*)&data_adr, sizeof(data_adr)) == -1)
error_handling("data connect() error!");
else
puts("Connected.....data...");
char buf[BUF_SIZE];
int read_cnt;
FILE *fp;
fp=fopen("../../usr/ftp/receive.dat", "wb");
while((read_cnt=read(sock, buf, BUF_SIZE ))!=0)
fwrite((void*)buf, 1, read_cnt, fp);
puts("Received file data");
fclose(fp);
return;
}