read,write를 사용하면 데이터가 잘립니다.

익명 사용자의 이미지

struct stat sb;
stat(url+1,&sb);
int size = sb.st_size;
int A;
char buf1[100000];
printf("%d\n",size);
int fd = open(url+1,O_RDONLY);

while((A = read(fd,buf1,sizeof(buf1))) >0)
{
write(client_fd,buf1,A);
}

소켓에서 file을 전송하는 코드입니다. file을 읽고, file 사이즈를 알아낸 다음에,
client에 file을 써서 보내주는 코드입니다.
다 쓰일 때까지 계속 파일을 읽어오고, 읽어온 뒤에 파일을 쓰는 기능을 하는데
이 기능이 앞에 50%정도만 전송이 되고 절반이 잘리게 됩니다. 이유를 도통 모르겠어서
질문을 드립니다. 제발 도와주세요 ㅠㅠ

라스코니의 이미지

파일 사이즈가 얼마나 되는지 모르겠지만

만약 100,000 바이트, 100kb를 read()에서 읽을수 있다고 치고 그것을 write() 함수로 보내게 되면 완전히 보내게 될 것인지 확인해 보세요. MTU가 1500으로 가정하면 실제 보낸 데이터를 write() 함수의 return 값으로 확인해서 다 못 보냈다면 못 보낸 부분부터 다시 보낼 필요가 있습니다.

질문의 이미지

while문을 사용했는데도 그 방법을 사용해야 하는 건가요????
사용해야 한다면 strlen을 사용해서 file pointer를 설정한 뒤 그부분부터 다시 write를 진행하면 되는 건가요?
복사된 뒤에 file size가 달라진 걸 보면 write가 문제인 건 맞는 것 같습니다.

질문의 이미지

크기가 10000BYTE가 안 되는 애들은 write 자체가 안 되고 넘어가더군요.
file pointer쪽의 문제인가 싶어서 file 선언할 때 rewind도 해주었는데
크기가 2.8만바이트인 파일은 복사하면 2.1만바이트정도로 줄어들고 사진이 잘려나옵니다.
이것도 write의 문제인가요?? 아니면 포인터 자체의 문제인가요??

라스코니의 이미지

스택에 100kb 를 선언하는 것도 문제가 될 수 있습니다. 가능하면 malloc()를 써서 메모리를 할당하는 것이 낫습니다.

라스코니의 이미지

A 만큼 읽었고, A 만큼 보내도록 하신거죠. write() 함수가 A 만큼 보낼수 없을수도 있음을 감안해서 write() 함수의 리턴값을 조사해서 만약 A 만큼 보내지 못했다면 그걸 감안하셔야 합니다.

질문의 이미지

B라는 인자를 한 개 더 선언해서
if((B =write(client_fd,buf1,A)) != A)같은 상태로 만들고,
write(client_fd,buf1+A,A-B)와같이 한 번 더 쓰라는 말씀이신 거 맞으시죠???

라스코니의 이미지

네. 맞습니다.

질문의 이미지

결과는 그대로 잘려서 나오고 있네요 ㅠ 혹시 코드적으로 제가 잘못 짠 게 있는지 여쭤볼 수 있을까요??

라스코니의 이미지

수정하신 코드 부분만 올려 보시죠.

질문의 이미지

struct stat sb;
	stat(url+1,&sb);
	int size = sb.st_size;
	int A,B;
	char *buf1 = (char*)malloc(sizeof(char)*100000);
	int fd = open(url+1,O_RDONLY);
 
	while((A = read(fd,buf1,sizeof(buf1))) >0)
	{
		if((B =write(client_fd,buf1,A)) != A)
			write(client_fd,buf1+B,A-B);
 
	}

B 인자를 선언해서 실패시 다시 쓰도록 설정했고, 위에 말씀하신 동적할당까지 적용해두었습니다!!
라스코니의 이미지

write() 부분도 또 하나의 while {} 루프에 들어가야 할 것 같습니다. B 값을 printf로 찍어 보는 것도 좋고요.

질문의 이미지

  while((A = read(fd,buf1,sizeof(buf1))) >0)
	{
		while((B =write(client_fd,buf1,A)) != A)
		{
			printf("%d\n",B);
			write(client_fd,buf1+B,A-B);
		}
 
	}

일단 루프를 선언하긴 했는데 제가 읽는 이미지는 한 번에 다 읽어서 오류없이 넘겨버리네요 ㅠ
printf B를 해보았으나 B가 하나도 나오지 않습니다.
파일 포인터에 초점을 맞춰서 생각해보는 게 좋을까요??
라스코니의 이미지

size를 프린트해 보세요. 파일 사이즈와 같나요?
중요한 값들을 다 찍어보시거나 디버그해보시면 도움이 되실 겁니다.

넵의 이미지

size까지 다 해보았습니다 ㅜ
size는 똑같이 받고, read 역시 문제 없이 size의 크기까지 완벽히 다 받습니다.
write하면서 문제가 생기는 것 같네요. 도와주셔서 감사합니다!!

라스코니의 이미지

보내는 쪽에서 문제가 없다면 받는 쪽에 문제가 있는 거겠지요. 그런 관점에서 받는 코드를 살펴 보세요.

넵!!의 이미지

도와주셔서 감사합니다. 좋은하루되세요 :D

댓글 달기

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