문제

C로 FTP 서버를 만들고 있습니다.클라이언트 측에서는 FileZilla를 사용하고 있습니다.지금까지 내 코드에는 핸드쉐이킹 부분만 포함되어 있습니다.

내가 가진 문제는 터미널에 대해 인쇄한 문자열이 FileZilla로 전송된다는 것입니다.내 질문은 이 두 가지를 어떻게 분리할 수 있느냐는 것입니다. 몇 가지를 시도했지만 그 중 어느 것도 올바른 결과를 얻지 못했습니다.

이것은 내 코드의 일부일 뿐이지만 내 질문에 유용한 부분은 다음과 같습니다.

while (FOREVER){
    addr_size = sizeof their_addr;

    newfd = accept(listener, (struct sockaddr*) &their_addr, &addr_size);
    if (newfd == -1){
        perror("accept");
        continue;
    }
    if ((send(newfd, "220 JEDI FTP is ready", 50, 0)) <= 0)
        perror("error sending");

    puts("connection established");
    puts("waiting for user & connection");
  while (!login){
        // username
        if (!user){
            if ((recv(newfd, buffer, BUFFCON, 0)) <= 0){
                puts("error receiving username");

            }
            else{

                if (strstr(buffer, "USER") != NULL){

                    if (strstr(buffer, name) != NULL){

                        send(newfd, "331 password required", 50, 0);
                        puts("username correct");

                        user = 1;
                    }
                    else{
                        puts("username incorrect");
                        send(newfd, "430 username incorrect", 50, 0);
                    }//else
                }//if
            }//else
        }//if user

FileZilla의 출력은 다음과 같습니다.

  • 상태:주소 bepalen van localhost
  • 상태:Verbinden이 [::1]:21을 만났습니다....
  • 상태:Verbound aangemaakt, welkomstbericht afwachten...
  • 앤트워드:220 JEDI FTP가 준비되었습니다
  • 특공대:사용자 요다
  • 앤트워드:연결이 설정되었습니다.
  • 아웃:Kan niet verbinden 만난 서버

따라서 "331 비밀번호 필요"를 보내는 대신 "연결 설정됨"을 보냅니다.

이 문제를 도와주셨으면 좋겠습니다. 정말 감사합니다.

도움이 되었습니까?

해결책

문제는 당신의 len 매개변수 send 너무 큽니다. send null로 끝나는 문자열에 대한 개념이 없습니다.원시 바이트 시퀀스에서만 작동합니다.그래서 전화 send(newfd, "220 JEDI FTP is ready", 50, 0) 문자열을 보낸다 "220 JEDI FTP is ready", 그리고 그 이후에 메모리에 떠오르는 모든 일이 발생합니다.기술적으로 이는 정의되지 않은 동작, 말 그대로 아무것 발생할 수 있습니다(보통 세그폴트).귀하의 경우 상수 리터럴 문자열은 일반적으로 메모리에 순차적으로 저장되기 때문에 send 주어진 문자열을 읽고 그 뒤에 다른 문자열을 읽는 것입니다.

당신이하고 싶은 일은 오직 정확한 문자열을 보내세요(그런데 CR-LF 시퀀스가 ​​필요합니다) \r\n 각 명령 뒤에).그 이상도 이하도 아닌.다음을 구현할 수 있습니다. sends 다음과 같이 문자열을 보내는 함수:

ssize_t sends(int fd, const char *str)
{
    size_t len = strlen(str);
    return send(fd, str, len, 0);
}

또한 전송된 데이터는 ~ 아니다 TCP 패킷이 문자열의 크기를 지정하므로 null 종결자를 포함합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top