이런 경우는 어떻게 처리하는게 좋나요?

superkkt의 이미지

주제를 뭘로할지 마땅치가 않네요.. 현재 간단한 파일 전송 프로그램을 짜고 있습니다.

/*
 * 전송된 데이터 기록
 */
void
data_write(FILE *fp, char *buf, int cnt, int sockfd)
{
	if(write(fp, buf, cnt) != cnt) {
		err_print("data write error");
		finish(fp, sockfd);
	}
}

위 함수는 네트웍으로 전송된 데이터를 넘겨주면 그걸 파일에 기록해주는 역할을 하는데요.. 일단 함수에 넘겨준 내용만큼 쓰기를 못하면 에러를 출력하고 종료하도록 만들었습니다.

finish함수가 열려있는 fd와 소켓을 닫고 종료하는 함수인데요.. 이 함수때문에 data_write함수에 sockfd라는 파라메터가 추가가 되었습니다. 데이터 기록하는 루틴과는 전혀 상관이 없고 단지 에러 발생시 finish함수한테 넘겨주기 위해서 받는건데요..

이런 경우엔 차라리 아래와 같이 함수를 바꿔서..

/*
 * 전송된 데이터 기록
 */
char
data_write(FILE *fp, char *buf, int cnt)
{
	if(write(fp, buf, cnt) != cnt) 
		return -1;
	
	return 0;
}

data_write를 호출하는 쪽에서 에러처리를 하는 방법도 생각을 해봤습니다. 근데 이렇게 하자니 단 몇줄이라도 호출하는 쪽에 더 추가가되고... 차라리 파라메터 하나 더 늘리는게 더 간단한걸까 싶기도하고..

두개중 어떤 방법이 좋을까요?

ㅡ,.ㅡ;;의 이미지

밑의 함수 궂이 이런함수 안만들어도 되지 않을까요..
함수남용같습니다만..


----------------------------------------------------------------------------

superkkt의 이미지

ㅡ,.ㅡ;; wrote:
밑의 함수 궂이 이런함수 안만들어도 되지 않을까요..
함수남용같습니다만..

다른 기능이 더 들어가야 되는데요.. 일단 뼈대만 만들고 있습니다. 기능이 다 들어가도 sockfd 파라메터는 쓸 일이 없습니다. 흠흠..

======================
BLOG : http://superkkt.com

yui의 이미지

저라면 data_write는 주어진 file pointer에 인자로 받은 내용을 써넣는 것만 신경쓰도록 하겠습니다. '인자로 받은 내용이 다른 fd(이경우엔 socket)에서 읽어온 것이고 따라서 쓰기 실패하면 fd까지 닫자' 라는 사항까지 알게 하는 것은 과도한 커플링이라 봅니다.
나중에 함수가 길어지다 보면 실수할 수 있는 부분이 될 수도 있구요.

fd에서 읽고 fp에 쓰는 것이 한번에 들어있는 함수라면 또 얘기가 다르겠습니다만. (그럼 왜 읽는 쪽은 fd고 쓰는 것은 FILE*냐는 의문이 떠오르고, 두개를 어떻게든 맞춰주려고 시도하던지 아니면 두개를 추상화 시켜서 입출력 포트 개념을 새로 구현해 넣고... 등등 으로 흘러갈 듯 하네요. :) 블라블라~)

@ 수도 코드로 적으신 것이겠으나 write의 첫번째 인자가 FILE* 이네요.

서지훈의 이미지

제가 볼때는 후자 쪽이 범용성 차원에서는 더 좋을거 같고...
특화된 기능을 위해선 역시나 전자가...
근데... 전자의 경우는 다른 곳에 사용하기에는 좀 무리가 있을듯 하고요...
후자의 경우는 단른 것들과의 연동도 가능 할듯 하네요.

저 같은 경우 해당 프로그램은 될 수 있음... main()에서 exit() or return()을 하고 있습니다.
그리고 이른 습관은 앞으로 큰 프로젝트를 하는데 있어 프로그램의 일관성에도 아주매우 중요한 역활을 하기도 해서 보통은 그리하는데...

그리고, 어떤 큰 프로그램에서도 garbage collection에 확실한 자신감이 있다면 중간에서의 exit()호출도 무관은 하지만... 역시나 인간이라는게 실수를 안하긴 힘들죠...

근데... 역시나 개인적인 간단한 프로그램이라면...
전자처럼 하는 것도 별로 나쁘진 않을듯 합니다.

<어떠한 역경에도 굴하지 않는 '하양 지훈'>

추신_음... 방 조도가 낮아서 화면이 좀 침침하네요 ㅡㅡㅋ

#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);

cronex의 이미지

man atexit

------------------------------------------------------------
이 멍청이~! 나한테 이길 수 있다고 생각했었냐~?
광란의 귀공자 데코스 와이즈멜 님이라구~!

doldori의 이미지

yui wrote:
저라면 data_write는 주어진 file pointer에 인자로 받은 내용을 써넣는 것만 신경쓰도록 하겠습니다. '인자로 받은 내용이 다른 fd(이경우엔 socket)에서 읽어온 것이고 따라서 쓰기 실패하면 fd까지 닫자' 라는 사항까지 알게 하는 것은 과도한 커플링이라 봅니다.
나중에 함수가 길어지다 보면 실수할 수 있는 부분이 될 수도 있구요.

동의합니다.

Prefer cohesion. Always endeavor to give each piece of code -- each
module, each class, each function -- single, well-defined responsibility.
-- Herb Sutter

쌀밥의 이미지

저는 후자쪽이 더 좋은것 같습니다.

그리고 에러가 난 경우 assert 를 사용하거나
log를 남기면 더 좋을것 같군요..

일하는 사람들의 희망 민주노동당 : http://www.kdlp.org
반공 교육의 성과로, 민주주의의 반대가 공산주의(또는 사회주의)라고 생각하는 사람이 많다.

superkkt의 이미지

main() --> func_a() --> func_b() --> func_c()

위 3개 함수는 모두 에러 발생시 -1을 리턴하는 구조입니다. 만약 func_c에서 에러가 발생했다면 func_c에서 에러메세지만 발생시키고 바로 종료하지 않고 -1을 리턴하고 상위 함수들은 그대로 -1을 리턴해서 마지막에 main에서 종료를 시키는게 이상적인 구조인가요?

아... 머리속에 궁금한게 이거랑은 조금 다른거 같은데 어휘력이 떨어져서 답답해 죽겠네요.. :evil:

======================
BLOG : http://superkkt.com

쌀밥의 이미지

func_a 수행에 실패 했다면 func_b는 수행을 안하는게 더 좋겠지요.

예로 드신것이 main 이라서 조금 다를수도 있지만

일반적인 함수를 만들때라면,

앞의 처리가 실패하면 바로 return 해야겠죠.

저는 주로 이런식으로 합니다.

const bool bRst1 = func_a(); // const 와 bool 은 C++의 키워드지요;;
if (false == bRst1)
{
assert(!"func_a에 문제가 발생");
return;
}

const bool bRst2 = func_b();
.....

아래 링크가 도움이 될지도 모르겠습니다. 참고하세요.
http://www.gpgstudy.com/forum/viewtopic.php?t=6491

일하는 사람들의 희망 민주노동당 : http://www.kdlp.org
반공 교육의 성과로, 민주주의의 반대가 공산주의(또는 사회주의)라고 생각하는 사람이 많다.

댓글 달기

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