socket 통신에서 소켓을 종료하지 않고도 EOF를 보낼 수
글쓴이: yanggak / 작성시간: 일, 2004/11/28 - 5:24오후
서버 클라이언트 프로그램에서 파일 송수신을 해보려는데
서버에서에서 클라이언트로 파일을 전송하는 방식입니다.
서버에서 파일을 열어서 read 로 읽고 이를 바로 write로 전송합니다.
파일을 다 읽으면 서버에서 read는 EOF를 만나 루프를 빠져나올텐데..
이렇게 파일을 다 읽었다는것을 클라이언트에서 알려주는 방법이
교재에서는 소켓을 종료하는 것으로 나와있어서요...
다른방법으로 클라이언트에게 알려주는 방법은 없을까요?
Forums:
FTP의 데이터 채널이나 HTTP 1.0 프로토콜들은 소켓이 끊어지면 데
FTP의 데이터 채널이나 HTTP 1.0 프로토콜들은 소켓이 끊어지면 데이터 전송이 완료되었음을 의미합니다.
그러나, 다른 많은 전송 프로토콜들은 데이터만 보내지 않고, 다른 의미가 들어있는 헤더들이 항상 전달됩니다. 이런 헤더안에 파일이 종료되었음을 넣어주면 되겠죠?
---
http://coolengineer.com
답변감사합다.헤더안에 정보를 포함시키라는 말씀이신것 같은데요..
답변감사합다.
헤더안에 정보를 포함시키라는 말씀이신것 같은데요..
구처적으로 어떤방법이 있는지요?
저도 인터넷을 뒤져보다보니깐 소켓이 종료되면 헤더안에
정보가 EOF로 바뀌어 전달된다는 문장을 읽었습니다.
그런데 제가 임의적으로 바꾸는 방법은 소개해주질 않아서..
헤더를 조정하는 특별한 함수가 있나요?
FTP는 데이터 연결 1개가 파일 하나니까 구분이 없고, HTTP/1.0
FTP는 데이터 연결 1개가 파일 하나니까 구분이 없고, HTTP/1.0도 마찬가지로 데이터 연결 1개가 URL 하나니까 구분이 없습니다. 즉 소켓 끊으면 종료되는 거죠.
HTTP/1.1같은 connection keep-alive기능이 있는데, 이건 헤더에 쓰인 크기만큼 받으면 연결을 끊지 않고 다음 요청을 기다리는 식입니다.
따라서 헤더 부분에 받을 파일 크기를 적어 주면 됩니다. 처음에 보내는 4바이트가 앞으로 나올 데이터 길이라든가... 여러가지 방법이 있겠지요.
--
익스펙토 페트로눔
답변해주신 분들이 얘기하는 헤더와 질문자님이 생각하는 헤더가 서로 다른것
답변해주신 분들이 얘기하는 헤더와 질문자님이 생각하는 헤더가 서로 다른것 같군요. 질문자님은 raw socket 의 어떤 헤더를 생각하시는것 같은데, 답변하신분들이 얘기하는 헤더는 '사용자정의 프로토콜에서의 의미있는 값'을 얘기하는것입니다.
걍 쉽게 예를 들어 서버에서 파일의 내용을 다 보내줬다면, "\f\n\f" 를 보내주기로 약속하고, 이를 보내주는것이지요. 하지만 보통 이렇게는 잘 안하고..(같은 내용이 파일에 있을수도 있으므로) 최초 몇바이트는 '헤더'부분으로 사용하며, 거기 보내는 파일에 대한 필요한 정보(크기를 비롯한 기타...)를 담아서 보내면 되겠지요.
뭐,..프로토콜의 정의란것은 딱 정해진 룰은 없는것이고 다양한 통신 프로토콜의 정의예들을 보시고, 사용하고자하는 시스템의 성격에 맞는 방법으로 프로토콜을 만드시면 될것 같으네요.
아...감사합니다.SaNha 님의 답변을 읽으니깐 좀 정리가 되네요.
아...감사합니다.
SaNha 님의 답변을 읽으니깐 좀 정리가 되네요..감사..
그러니깐 제가 임의로 보내는 정보에 서버에서
식별할 수 있는 어떤 규칙을 정하라고 말씀하시는것 같은데...^^
궁금한게 또 있는데요...
책을 보니깐 소켓으로 전달되는 정보는 buffer에 저장되어서 전달된다고 나와있는데요..
그렇다면 제가 write할때 바로 전송되지 않는다는 뜻이 되니요?
그럼 위와 같은 방법을 사용하면 어떻게 묶여서 전송될지 모르지 않나요? 아니면 책에서 설명하는 버퍼를 전송할때 마다 바로바로 비워줘야되는건가요??
If you can dream it,
you can do it
답변해주신 방법으로 해결했습니다..감사합니다...많이 실력이 부족
답변해주신 방법으로 해결했습니다..
감사합니다...많이 실력이 부족하네요...^^;
하지만 버퍼의 의미는 좀 궁금하네요....^^;
(^^) (__) (^^) 답변 감사합니다.
If you can dream it,
you can do it
buffer에 대하여...
버퍼에 대한 답변 글이 없길래 적습니다
우선, 제가 적는 내용은 틀릴수 있다는 점을 말씀 드리고 ^^
(우선 저 자신이 잘 모르므로)
정말 정확히 알고 싶으시다면 다른 곳에서 참고를 하시기를 말씀 드리고
싶습니다.
우선 , 소켓이 생성되면 출력 버퍼와 입력 버퍼가 생성이 된다고 알고 있습
니다.(저의 설명중 틀리는 부분은 지적을...)
이는 표준 라이브러리 함수의 printf등이 stdout, stdin, stderr과 같은
버퍼를 가지고 있는 것과 같지요. 이는 중간 기억장소를 둠으로서 지나치게
빈번한 입출력을 막고, 방대한 네트워크의 과부하를 줄이기 위하여 수차에
보내는 것을 막고 모아서 보내기위함으로 알고 있습니다.
또한, 상대방의 입력 버퍼가 다 차 있다든지 하여
미처 받을 준비가 안 되어 있을때 데이터를 보내면
데이터를 손실하게 되므로 기다리는 동안 데이터를 저장하는 역할
(이를 흐름제어라 합니다..)로 이용되기도 하지요.
물론, 송신자의 입력,출력버퍼는 송신자의 컴퓨터내에서 보낼(혹은 받은)
데이터를 임시적으로 저장하는 기억공간이고, 수신자의 버퍼 역시
그렇습니다. 제가 가진 지식에 한하여 말씀 드리면 패킷으로 보내는
데이터는 기본적으로는 바로바로 보내는것이라고 알고 있습니다.
단, Nagle알고리즘이라는 것이 있는데 이것은 소켓을 사용하실때에
socketopt를 이용하여 설정 하실수가 있는데요, 이것이 무엇이냐 하면은,
우선 첫번째 데이터를 보냅니다. "12345"라는 문자열을 보낸다 할때,
먼저 1 이 날아가겠지요? 그 후에는 일단 버퍼에 데이터가 들어와도
보내지 않고, 수신측에서 잘 받았다는 ack신호가 올때까지 기다립니다.
원래는 1,2,3,4,5순서대로 버퍼에 들어오는 즉시 5번의 전송을 하는 것이
정상이나, 수신측에서 보낸 ack신호가 송신측에 도착할때까지 데이터를
전송하지 않음으로 2,3,4,5는 버퍼에 쌓이게 되고, 수신측에서 보낸 ack
가 송신측에 도착한 순간 다시 데이터를 보내게 되는데, 이때 2,3,4,5가 묶
인 하나의 패킷이 전송되는 것이지요. 이것이 Nagle알고리즘으로 네트의
과부하를 줄이기 위한 하나의 방편입니다.
즉, 5회의 전송이 필요한 작업을 2회의 전송으로 끝내는 것이지요
아직 모르는 것이 많아 적은 내용중 어디가 틀렸는지 알수 없으며
(답변자로서 신용이 없군요^^)
그리고 당연히 알고 계시리라 생각하지만 데이터를 다 읽었고,
더이상의 데이터를 읽을 일이 없다면 shutdown()을 사용하시는 것은
어떠신지요. 더이상 읽을 데이터가 없다면 소켓의 읽기, 쓰기 스트림중
읽기 스트림만 닫아 버리면 자신이 상대로부터는 읽지는 못해도
상대에게 전송은 가능하니까요.
(shutdown()사용시 EOF가 전송된다고 알고 있습니다.)
위의 raw소켓이 뭔지도 모르면서 헛다리 짚는 답변을 한것같아
걱정이 되지만 버퍼에 관하여는 의도 파악을 제대로 했다고 생각하여
한번 적어 보았습니다.
그럼이만..
^&^
tcp에서 EOF란 데이타를 보내지 않읍니다.
shutdown을 하며 FIN이 전송이 되죠 ^^
댓글 달기