download를 보통 어떻게 구현 하나요?

jude1064의 이미지

파일 공유 프로그램을 만드는데 download 부분만 남았습니다.

보통 파일 다운로드를 어떻게 구현하는지요?

그냥 write함수에 써버리면 되나요?--;;

아님 다른 프로토콜의 API를 사용하는지..

간단한거 같은데.. 닥치니까 좀 난감하네요..

참고할만한 자료좀 부탁드립니다.~

Necromancer의 이미지

파일을 읽어들인 다음 적당한 크기로 짤라서 보내주면 됩니다.
네떡이 받쳐준다면 한방에 다보내도 되구요.
보낼때는 읽어들인 파일데이터를 send()로 날리면 됩니다.

다만 중간에 끊어지는 경우에 대한 대비는 있어야겠죠.
파일데이터 보낼때 이런 목적의 헤더 부분을 붙이죠. 구조는 설계자 맘대로.

UDP로 보내면 시퀀스제어까지 해야 하구요

p.s.

send는 write와 달리 전송해달라는 데이터를 한번에 다 안보내는 경우가
있습니다. 따라서 send() 뒤에는 꼭 보낸 바이트수를 체크해야 됩니다. 덜썼다면
그부분부터 다시쓰고.

Written By the Black Knight of Destruction

익명 사용자의 이미지

Quote:

send는 write와 달리 전송해달라는 데이터를 한번에 다 안보내는 경우가
있습니다. 따라서 send() 뒤에는 꼭 보낸 바이트수를 체크해야 됩니다. 덜썼다면
그부분부터 다시쓰고.

아...그런 차이가 있었나요?
흠...처음 듣는 말이네요... 좀 설명좀 부탁드립니다.

Necromancer의 이미지

write()로 10000바이트 썼다고 칩시다.

그러면 write()는 무조건 10000바이트 다 쓸때까지 기다립니다. 그리고
리턴합니다. 만일 10000바이트를 쓰다가 중간에 도저히 쓸 수 없는 상황이
발생한 경우 에러코드 세팅되고 -1이 돌아옵니다.

하지만 send()로 10000바이트를 쓰라고(보내라고) 요구했다면,

send()는 10000바이트를 다 쓰고 리턴하는 경우도 있지만, 500바이트
내지 1000바이트만 달랑 쓰고 리턴하는 경우도 있습니다. 리턴시 쓴 바이트수가
리턴되는건 아시죠.
이경우 9500바이트(500바이트만 쓴 경우)나 9000바이트(1000바이트 쓴 경우)
가 전송되지 않은 채로 남습니다. 얘네들은 다시 send()를 해줘야 되죠. 다
전송될때까지 반복해서.

Written By the Black Knight of Destruction

mithrandir의 이미지

Quote:

send는 write와 달리 전송해달라는 데이터를 한번에 다 안보내는 경우가
있습니다. 따라서 send() 뒤에는 꼭 보낸 바이트수를 체크해야 됩니다. 덜썼다면
그부분부터 다시쓰고.

맨페이지를 찾아봤지만, send, write 둘다 return값이 전송(쓴)한 바이트수 라는 설명밖에는 찾을 수가 없었습니다.

어딜 살펴봐야 할지 가르쳐주시면 감사하겠습니다.

언제나 삽질 - http://tisphie.net/typo/
프로그래밍 언어 개발 - http://langdev.net

Necromancer의 이미지

10000바이트를 send()했다 할찌라도 10000이 아니라 500이나 1000 정도만
리턴되는 경우도 있다는 말입니다. 이경우 나머지는 다시 send()해야 합니다.

Written By the Black Knight of Destruction

musik의 이미지

안녕하세요~

write() 가 '소켓'에 대해 쓰기를 시도 하는 경우, 10000바이트를 인자로 넘겼다고 해서 반드시 10000바이트가 다 쓰일때까지 블럭킹 되지는 않습니다.

이 경우 write() 라는 것은 단지 네트웍 레이어의 버퍼에 복사되기 까지의 과정이므로, 네트웍 프로토콜의 현재 상태에 따라서 복사 가능한 바이트의 수가 정해지겠지요.

물론 일반 파일이라면 얘기가 다르겠습니다만...

그럼 건강하세요.

jinyeong의 이미지

파일을 보내실때가 문제이신건가요?

read from local_file
write to socket

으로 쓰면 되겠지요.. 물론 위에서 말씀하신 것 처럼,
보낸 바이트 카운트 정도는 필수일테구요.

파일을 받을때라면 반대로 하시면 되겠지요..

그리고 사용하시는 OS가 linux라면 파일을 보낼때는

sendfile 하나로 대체 가능하고,

어느 정도의 성능 향상의 효과를 보실 수 있을 겁니다.

I thought what I'd do was,
I'd pretend I was one of those deaf-mutes.. or should I?

bw001730의 이미지

흑기사 wrote:
10000바이트를 send()했다 할찌라도 10000이 아니라 500이나 1000 정도만
리턴되는 경우도 있다는 말입니다. 이경우 나머지는 다시 send()해야 합니다.

그니깐..흑기사님 말씀자체는 이해가 되었습니다. ^____^
흑기사님 말씀과 같은 내용을 참조할 만한 문서라도 있는지...
그게 궁금하군요

얼핏 생각하기엔 write나 send가 다를 이유가 없을거 같거든요
write나 send나 커널 내부적으로는 같은 함수를 가리키고(포인터) 있을것 같아서요. 함수포인터로.

제가 커널을 잘 몰라서..그냥..궁금한데요
이런 저런 문서를 살펴봐도 흑기사님 말씀이 나온 글을 못찾겠어서요

emptysky의 이미지

음... 몰랐던 사실이네요
보통 큰사이즈의 파일을 전송할때 루프안에 write 나 send를 돌리게 되는데
(물론 한번보내고 말거 아니라면 아주 작은 사이즈에서도 루프안에서 돌리겠죠)
윗분 말씀대로라면 하나의 파일 전송시 write 사용한다면 파일 사이즈에 상관없이 루프가 필요없다는 말씀인가요?

『 아픔은.. 아픔을 달래줄 약이 무엇인지 알면서도 쓰지 못할 때 비로소 그 아픔의 깊이를 알수가 있음이다. 』
『 for return...』

익명 사용자의 이미지

음, 제가 알기론 실제론 send 또한 어떻게든 데이터를 모조리 전송한다고

알고 있습니다. recv의 경우는 데이터가 들어있기만 하면, 가져오기 때문에

100을 설정해도, 1, 2, 부터 100까지 들어올 수 있지만, send의 경우는

그냥 모조리 전송하는 걸로 알고 있습니다. 고운 하루되세요.

익명 사용자의 이미지

musik wrote:
안녕하세요~

write() 가 '소켓'에 대해 쓰기를 시도 하는 경우, 10000바이트를 인자로 넘겼다고 해서 반드시 10000바이트가 다 쓰일때까지 블럭킹 되지는 않습니다.

이 경우 write() 라는 것은 단지 네트웍 레이어의 버퍼에 복사되기 까지의 과정이므로, 네트웍 프로토콜의 현재 상태에 따라서 복사 가능한 바이트의 수가 정해지겠지요.

물론 일반 파일이라면 얘기가 다르겠습니다만...

그럼 건강하세요.

위의 musik 님께서 정확하게 말씀을 해주셨는데도 불구하고 자꾸 write 는
한번에 보낸다는 등... 틀린말씀들을 하고 계시니 쩝.... -_-;;;;;
write 든 send 든 데이타를 전송할때는 반드시 루프를 돌려 '남김없이'
쓰도록 하세요 .

그럼이만~

Necromancer의 이미지

여기 위키에 올라온 문서에도 있습니다.

http://wiki.kldp.org/wiki.php/BeeJNetworkProgramming#s-4.6

send,recv 설명절인데 잘 보면 있습니다. 대량의 데이터를 한꺼번에 보내는
경우 send()는 일부만 보내고 리턴합니다.

IP프로토콜은 구조상 패킷 크기 한계가 64k입니다.
MTU를 고려한다면 더 작아지겠죠.
물론 커널에서 가능한한 한번에 다 보낼려고 하지만 이런 제약에 걸리면 한번에
다 보내지 않습니다. 유저보고 다시 send(), recv()해달라고 주문합니다. 대부분
1k 내외 정도의 크기면 한번에 다 보낸다고 보시면 됩니다.

음... 그러고보니 소켓에 대해서는 write도 send와 똑같이 작동한다는건 오늘 처음 알았네요.

Written By the Black Knight of Destruction

byung82의 이미지

blocking 모드 일때는 send, write하면 전송이 완료 될때 까지 대기 하지 않는가요 ^^;

blocking 과 nonblocking일때 차이인데 blocking으로 하신다면 return 되는 byte를 보시고 판멸 하시면 되며,

nonblocking 일때는 하번에 다 보내지 않으니 전송 byte를 확인 하셔야 합니다 ^^;

그럼

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.