소켓 프로그래밍 관련 질문입니다..

익명 사용자의 이미지

이번에 학부 프로젝트로 소켓 프로그래밍을 하게 되었습니다. 프로그래밍
경력은 수업들으면서 약간 해본 것 뿐입니다.

여기 게시판이랑 codeguru 좀 찾아봤는데 제가 알고자 하는 것을 찾지 못
했습니다.

client(C)는 vxworks가 탑재된 ppc 860보드이고(근데 tcp/ip 프로그래밍
은 일반 유닉스에서와 거의 똑같더군요..),
server(visual C++)는 window에서 mfc를 이용해서 짜고 있습니다.
CAsyncSocket class인가를 이용해서요..(사실 mfc도 며칠 전부터 책보고
시작..-.-)

데이터를 주고 받는 건 성공했는데.. char 버퍼로 만 몇개까지는 가는데
그 이상의 데이터를 한번에 보내니 잘 못받더군요.

예를 들어 char array로 size 20000만큼, 그러니까 20KB가량 보내니
17502개 만큼 밖에 못 받습니다. 더 많이 보내도 그게 한계더군요..

제가 생각하는 원인(여기저기 뒤져봤죠)은 MTU 값에 의한 제한때문에 그렇
게 되는 것과,
또 codeguru에서 얼핏 보니 mfc에서(또는 winsock) 한번에 많은 양을 SEND
하거나 하면 제대로 못 받는다더군요. 뭐 자세히는 모르겠지만 메시지 핸
들러가 계속 호출되면서 뭐 어쩌구 저쩌구 하는데.. 서버라 받기만 하지만
class상의 함수에 좀 문제가 있지 않나 하는 추측도 듭니다.

어쨋든 저 MTU라는 것 때문이라도 데이터를 쪼개서 보내는 수밖에 없는 것
같습니다..

근데 이거 실제로 구현하려고 하니 잘 모르겠네요.. codeguru에서 그런 식
으로 보내는 것도 없는 것 같고..

질문
client에서 보낼 때 수십 kB를 쪼개서 보내려면 어떤 함수를 써야할까요?
그쪽 함수를 잘 몰라서..

파일에 차곡차곡 쓰는 방법을 여기서 본 것 같은데 그런 방법은 안 쓰려
합니다.

꼬리질문
ftp 프로그램도 조금씩 쪼개서 보낼 것같은데 맞는지..

글고 위와 관련된 링크도 좋습니다..

답변해 주실 분께 미리 감사드립니다.

익명 사용자의 이미지

MFC 환경에서의 소켓클래스에 대해서 확실하게는 모르지만
(제가 유닉스 환경에서만 플밍을 하는 관계로)

유닉스 환경에서 socket 함수를 이용해서 플밍할적에도 짧은 시간에 다량의 패킷을
보낼때 위와 같은 현상이 나타납니다.
특히 패킷을 파일스트림을 통해서 보낼적에 패킷이 유실되는(실제 유실되는건
아닙니다만, 파일스트림을 처리하는 함수의 특성상) 현상이 발견됩니다.
read 를 통해서도 마찬가지이구요.
패킷단위로 처리할경우 패킷단위로 끊어지지 않고, 뒤에 패킷이 붙어 버리는 현상이
발생합니다. 이런이유로.. . 보통은 패킷을 헤더와 바디로 구분해서 헤더에
전체 패킷의 사이지를 입력해서 패킷의 크기를 검사해서 재 조립 하는 과정을
거칩니다. 꽤 귀찮은 작업이지요.
그래서 이러한 귀찮은 작업을 위해서 받아들일대 read 로 받아들이고,
이를 파일스트림을 통해서 처리하는 방법을 이용합니다.
그럼 패킷이 붙어서 오는 문제도 해결되고, 귀찮게 일일이 패킷의 크기를 검사하지
않아도 되지요..

MFC 에서도 이러한 문제 때문이 아닐까 라는 생각이 듭니다.
별도의 처리를 해주지 않으면 패킷이 붙어서(뒤죽박죽) 들어오고 특히
스트림 데이타라면 데이타 유실이 발생할겁니다.

ps. 앞에서 말씀드렸듯이 MFC 에 대해서는 전혀 모르는 상태에서
유닉스 쪽에서 비슷한 경험이 있어서 말씀드린 겁니다.

익명 사용자의 이미지

UNP에 나온 소스입니다.

ssize_t /* Write "n" bytes to a descriptor. */
writen(int fd, const void *vptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
const char *ptr;

ptr = vptr;
nleft = n;
while (nleft > 0) {
if ( (nwritten = write(fd, ptr, nleft)) <= 0) {
if (errno == EINTR)
/* and call write() again */
nwritten = 0;

else
return(-1); /* error */
}

nleft -= nwritten;
ptr += nwritten;
}
return(n);
}

익명 사용자의 이미지

답장 감사합니다..

지금 보드가 부팅이 안 되서 client를 실험못하고 있는데

님의 말대로 server에서는 read한후 파일 스트림에 쓰는 방식으로

해보려 합니다..

익명 사용자의 이미지


답장 감사드립니다..

UNP가 unix network programming 맞죠?

저도 그 책 도서관에서 빌려두었는데 변변치 못하게 잘 읽지도 않아서..
^^

제가 빌린 책은 90년도에 나온거 같은데(표지에 파란색으로 글자가 쓰여
진..) 책 279페이지에 writen function과 제가 몰랐던 이유가 나오네요..

님이 올리신 소스와 약간 틀린데 다른 분 참고하시라고 올립니다.

책 설명 부분

/*
stream socket exhibit a behavior with the read and write system

calls that differs from normal file I/O. A read or write on a socket

might input or output fewer bytes than requested, but it is not an

error condition. the reason is that buffer limits might be reached

for the socket in the kernel and all that is required is for the

caller to invoke the read or write system call again, to input or

output the remaining bytes. some versions of Unix also exhibit this

behavior when writing mode than 4096 bytes to a pipe.

*/

간단한 영어니 아시겠죠?

/*
* write n bytes to a descriptor.
* Use in place of write() when fd is a stream socket
*/

int writen(register int fd, register char *ptr, register int nbytes)
{
int nleft,nwritten;

nleft = nbytes;
while(nleft>0){
nwritten=write(fd, ptr, nleft);
if(nwritten <=0)
return (nwritten);

nleft -= nwritten;
ptr += nwritten;
}
return (nbytes - nleft);
}

반복해서 write 함수를 call 하는군요... -.-;

밑에 글쓴대로 보드가 부팅안되는 먹통 상태라 테스트는 안 해봤습니다..

될 것 같은 예감이..

readn 함수도 존재하네요.. 위 함수와 99% 똑같으니 바꿔서 쓰시면 될듯..

흠, writen 함수는 그대로 써먹으면 될 것 같은데..
readn 은 mfc에 써먹을려면 class를 뜯어 고쳐야 하나.. 약간 생각해서
짜야겠네요..

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.