수다닷컴

  • 해외여행
    • 괌
    • 태국
    • 유럽
    • 일본
    • 필리핀
    • 미국
    • 중국
    • 기타여행
    • 싱가폴
  • 건강
    • 다이어트
    • 당뇨
    • 헬스
    • 건강음식
    • 건강기타
  • 컴퓨터
    • 프로그램 개발일반
    • C언어
    • 비주얼베이직
  • 결혼생활
    • 출산/육아
    • 결혼준비
    • 엄마이야기방
  • 일상생활
    • 면접
    • 취업
    • 진로선택
  • 교육
    • 교육일반
    • 아이교육
    • 토익
    • 해외연수
    • 영어
  • 취미생활
    • 음악
    • 자전거
    • 수영
    • 바이크
    • 축구
  • 기타
    • 강아지
    • 제주도여행
    • 국내여행
    • 기타일상
    • 애플
    • 휴대폰관련
  • 프로그램 개발일반
  • C언어
  • 비주얼베이직

리눅스와 윈도우 간에 소켓통신(파일 전송) -해결

볼수록매력

2023.04.01

파일 전송을 하는데 보내는쪽은 윈도우고 받는쪽은 리눅스입니다.

보내는쪽(윈도우)은 버퍼출력스트림을 쓰고
toclientfile = new bufferedoutputstream(new dataoutputstream(socket.getoutputstream()) );

아래 소스로 파일을 전송합니다.
// 4k씩 보내는데 처음 3바이트의 첫번째는 그냥 0 , 두번째와 세번째는 파일의 패킷의 크기를 보냅니다.
// 그리고 파일에서 4093바이트씩 읽어서 보내는데, 파일 마지막에 4093이 안될경우 그냥 쓰레기값으로 4케이 채워서 보냅니다.
// 처음 3바이트 + 파일에서 읽은 4093바이트 해서 4096바이트씩 보냅니다.
//그리고 마지막에 3바이트만 보내 파일전송의 끝을 알립니다.
bufferedinputstream fromfile = new bufferedinputstream( new fileinputstream(sendfile));
int len = 0;
int buffersize = 4096;
byte[] buffer = new byte[buffersize];
buffersize -= 3;
while( (len = fromfile.read(buffer, 3, buffersize) ) != -1 ){

buffer[0] = (byte)0x00;
buffer[1] = (byte)((len0) & 0xff);
buffer[2] = (byte)((len8) & 0xff);
//system.out.println(size= +len); 파일 사이즈를 바이트로 변환
len = ((int)buffer[2]&0xff)8 | ((int)buffer[1]&0xff)0;
//system.out.println(check size= +len);잘 변환됫는지 확인
toclientfile.write(buffer,0, 4096);
toclientfile.flush();
}
//아래 부분 3바이트는 파일 전송이 완료됐다는걸 알리는 부분입니다.
buffer[0] = (byte)0x00;
buffer[1] = (byte)0x00;
buffer[2] = (byte)0x00;
toclientfile.write(buffer,0, 3);//000이 아니면 끝이 아님(패킷손실?)
toclientfile.flush();받는쪽은 리눅스인데..
//4k씩 받아서 처음 3바이트는 파일 크기를 알아내고 파일크기만큼 파일에 씁니다.
//파일전송중이면 4093바이트씩 파일에 씁니다.
//보내온 패킷이 4096이 안될경우는 처음 3바이트를 조사하여 0 0 0 이 되면 파일 끝
//
fromserverfile = new bufferedinputstream(new datainputstream(socket.getinputstream()));
tofile = new bufferedoutputstream(new fileoutputstream(file));
boolean isend = true;
int missingcount = 0; //exception이 날 경우 +1 된다.
while( isend ){
if((fromserverfile.read(buffer) ) == 4096){
len = ((int)buffer[2]&0xff)8 | ((int)buffer[1]&0xff)0;
//system.out.println(size: +len+ buffer: +buffer.length);
try{
tofile.write(buffer,3,len);
tofile.flush();
}catch (exception e) {
system.err.println([java]file recieve error: +
file.getname()+ size: +len);
e.printstacktrace();
if(missingcount5){
system.err.println([java]error network);
break;
}
missingcount++;

}

}else{
isend = !( (buffer[0] == (byte) 0x00) &&
(buffer[1] == (byte) 0x00) &&
(buffer[2] == (byte) 0x00) ) ;
system.out.println( buffer[0] + +buffer[1] + +buffer[2]+ +isend );
missingcount++;
if(missingcount7){
break;
}
}
}근데 윈도우에서 같은 프로그램을 실행시키면 잘 되는데..
리눅스-윈도우 간에 실행시키면 될때도 있고 안될때도 있네요-_-;;

에러가 날때는 파일 크기를 알려주는 byte[0], byte[1], byte[2]의 값이 이상한 값이 오는데..-_-;;
왜 그런건지 당체 모르겠습니다.

파일 전송의 끝을 보통 방식처럼 -1로 안한건 소켓연결유지상태서 여러 파일을 전송하기 위해서입니다.

조언 부탁드립니다.

신청하기





COMMENT

댓글을 입력해주세요. 비속어와 욕설은 삼가해주세요.

  • 게자리

    흐;; 주말이니 좀 더 연구해봐야겠네요.

  • 꽃짱아

    OS마다 버퍼의 크기가 다르기 때문에 그렇습니다.
    그리고 windows도 꼭, 4096으로 잘라서 보내지 않습니다.
    ( 네트워크 관련 책에 보면 나와 있지요. API에도 그렇게 적혀 있고.. )

    그러니 시간이 되신다면 잠깐 짬을 내어 지금 고치시는것이 더 좋을듯 해 보입니다. ^^;;;

  • 든해솔

    훈훈한글이네요 ㅎㅎ

  • 데빌의눈물

    찬님 말씀이 맞네요. 원인은 2번이 확실합니다.

    if((fromServerFile.read(buffer) ) == 4096){ 이 부분을
    if( (readCount= fromServerFile.read(buffer) ) == 4096){ 이렇게 변경하고 에러가 날때

    readCount 를 출력하니 2896이 나오네요.
    다음 패킷부터는 2897번째 비트부터 4096으로 짤라서 보내니 알 수 없는거 였습니다.

    다른 환경에서는 어쩔지 모

  • 홀림길

    2. 송신측에서 4096으로 보낸다고 해서, 수신측에서 4096으로 받으라는 보장은 절대 없습니다.
    그러므로 저렇게 해서는 문제가 발생할 가능성은 언제든지 존재합니다.

    아마도 될때도 있고 안될때도 있고 하는 것은, 2번의 문제 때문에 발생하는것으로 보이네요.

    꼭 4096만큼 읽어야 한다면,
    그냥 readCount와 readBuffer를 두어서, 아직 도착한 데이터가 4096바이트 보다 작으면,
    readBuffer에 쌓아 두셨다가, 쌓아둔 데이터가 4

  • 흰양말

    그리고 미치겟는건..아싸리 안된려면 계속 안되거나.. 되면 계속 되야되는데..될때도 있고 안될때도 있어서... ㅠ_ㅠ

  • 가자

    찬님 //1. 일단 VM이 틀립니다. ㅠ_ㅠ 임베디드라서 cee-j vm을 사용합니다.(일반 버전으론 1.42정도)

    2. 수신부에 byte buffer[] = new byte[4096]; 이 부분이 빠져서 헷갈리셧는지도.. 송신측에서 파일전송시에는 무조건 4096으로 보내고 flush하기 때문에 받는쪽에서도 파일받을때는 무조건 4096씩 받는거라고 가정했습니다.

    3. buffer[0]~[2]까지는 헤더부분이라 보낼때 그 부분엔 파일의 내용을

  • 보늬

    같은 java vm끼리면, 문제가 안 되지 않을까요? 잘 모르겠습니다. ^^


    제가 궁금한건

    받는 쪽 소스의
    while( isEnd ){
    if((fromServerFile.read(buffer) ) == 4096){

    이 부분이 좀 이상해 보입니다.
    formServerFile에서는 read를 하면 4096이 나올 수도 있고 안 나올 수도 있습니다.
    ( buffer에 읽어 들인 양을 반환하기 때문에 )

    만약 4096이 안나온다고 해서 b

  • 오나미

    감사합니다. 아 이제 저걸 어떻게 통일하냐가 문제군요.. nio에서는 바이트오더를 제어해주던데.. 임베디드라 제한되어있는 함수만 있으니..노력해봐야겠습니다+_+

  • 솔관

    이건 빅엔디안이냐 리틀엔디안이냐 문제네요. 네트웍으로 데이터를 전송할 때 CPU마다 byte stream방식이 틀려 생기는 문제입니다.

번호 제 목 글쓴이 날짜
2697366 에..조금 짜보고 다시 질문입니다. (2) 나샘 2025-06-07
2697333 li 가운데 정렬.....도와 주세용... (7) 초고리 2025-06-07
2697284 이미지를 흐리게 (2) 난새 2025-06-06
2697258 VC++ 6.0(studio)을 깔면서 재미가 붙었는데..ㅠㅠ (4) 앵겨쪼 2025-06-06
2697228 WorkFlow가 궁금합니다.. 다들 어떻게 하시는지.. (1) 애기 2025-06-06
2697174 button 태그와 input 태그의 type 속성을 사용한거와 차이 (1) 여름 2025-06-05
2697149 익스플로러에서 이미지로딩이 느려지는건지..깨져서 나옵니다. (4) 든솔 2025-06-05
2697122 호환성질문 (5) 미즈 2025-06-05
2697066 웹에서 다른이름으로 저장 할때 파일 이름 저장하는 방법은? 코이 2025-06-04
2697043 position:absolute; 로 하면 사라져 버리는 이유 ㅠㅠ (3) 풍란 2025-06-04
2697016 테이블 thead tbody 질문 아란 2025-06-04
2696989 contact us 페이지는 dl로 작성하는게 좋을까요? (4) 파라 2025-06-03
2696964 img 태그 질문드려요 (9) 연블루 2025-06-03
2696907 [질문] 올플래시 메뉴 고정할수 있는[수정] (4) 맨삶이 2025-06-03
2696875 책구입 후 따라하다가 ShortCode Ultimate 오류 가지등 2025-06-02
2696844 css 마우스 오버시 display:block되는 영역 질문드립니다 ㅠㅠ (2) 갅쥐누뉨 2025-06-02
2696816 엉엉엉...영상이 올라타네요 (5) 다은 2025-06-02
2696792 Doctype 문의 떠나간그녀 2025-06-02
2696683 컴파일된 클립 질문 드립니다. 흰추위 2025-06-01
2696656 C질문요 (4) 블랙캣 2025-05-31
<<  이전  1 2 3 4 5 6 7 8 9 10  다음  >>

수다닷컴 | 여러분과 함께하는 수다토크 커뮤니티 수다닷컴에 오신것을 환영합니다.
사업자등록번호 : 117-07-92748 상호 : 진달래여행사 대표자 : 명현재 서울시 강서구 방화동 890번지 푸르지오 107동 306호
copyright 2011 게시글 삭제 및 기타 문의 : clairacademy@naver.com