Linux c网络编程)我无法连接到第二个插槽

时间:2015-05-30 19:20:38

标签: c linux sockets networking tcp

发送简单消息在此程序中正常工作。

但是当我发送文件时它有一些问题。

还有另一个具有不同端口的套​​接字。

我做了另一个插座。

但是在绑定之后,当在服务器中调用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;
}

0 个答案:

没有答案