도와주세요 ㅠㅠㅠㅠ 소켓 통신 파일전송 입니다 ㅠㅠㅠㅠ 제발루요 ㅠㅠ

-@Naver의 이미지

import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

public class FileSendClient extends Frame implements ActionListener{
FileDialog fd;
Button b1,b2;
TextField tf;
String directory="", file="";

/* 아시죠? 프레임을 구성할 컴포넌트들 생성함*/
public FileSendClient() throws Exception{
b1=new Button("파일선택");
b1.addActionListener(this);
tf=new TextField(25);
b2=new Button("파일전송");
b2.addActionListener(this);
add(b1,"North");
add(tf,"Center");
add(b2,"South");
setBounds(200,200,100,100);
setVisible(true);
}

/* 버튼에 액션 발생시 실행됨 */
public void actionPerformed(ActionEvent ae){

try{

/* 파일선택 다이얼 로그가 뜨고 */
if(ae.getActionCommand().equals("파일선택")){
fd=new FileDialog(this,"",FileDialog.LOAD);
fd.setVisible(true);
tf.setText("");

/* 선택했을 경우 디렉토리와 파일명이 저장됨 */
directory=fd.getDirectory();
file=fd.getFile();
tf.setText(directory+file);

/* "else" 파일전송버튼 클릭시 실행됨 */
}else{

/* localhost 부분은 상대편 ip 주소를 입력하고, 3333 은 서버측 포트와 동일하세 세팅 */
Socket s=new Socket("localhost", 3333);

/* 소켓으로부터 OutputStream 얻어서 파일명을 먼저 보냄 */

/* 서버측에서 파일 객체 생성시 이용할 것임 */

BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
bw.write(file+"\n"); bw.flush();

/* 선택한 파일로 부터 스트림을 읽어들여서 얻어놓은 OutputStream에 연결 */

DataInputStream dis=new DataInputStream(new FileInputStream(new File(tf.getText())));
DataOutputStream dos=new DataOutputStream(s.getOutputStream());


/* 바이트단위로 읽어서 스트림으로 쓰기 */
int b=0;
while( (b=dis.read()) != -1 ){
dos.writeByte(b); dos.flush();
}

System.out.println("파일명 : "+file);

/* 자원정리
dis.close(); dos.close(); s.close();
dis=null; dos=null; s=null;
System.exit(1);
*/
}
}catch(Exception e){
System.out.println(e);
}
}

/* 메인 */
public static void main(String args[]) throws Exception{
new FileSendClient();
}
}

=> 클라이언트

import java.net.*;
import java.io.*;

public class FileSendServer{
public static void main(String args[]) throws Exception{

/* 3333포트로 서버소켓을 생성 */
ServerSocket ss=new ServerSocket(3333);

/* 클라이언트가 접속할때 까지 기다림 */

/* 접속하게 되면 클라이언트와 데이터를 주고 받을수 있는 유일한 소켓을 열어줌 */
Socket s=ss.accept();
System.out.println("소켓 "+s+" 에 연결됨");

/* 소켓으로부터 스트림 얻어옴 */
// InputStream is=s.getInputStream();
//BufferedReader br=new BufferedReader(new InputStreamReader(is));

/* 저장할 파일의 객체 생성함 */

while(true) {
InputStream is=s.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(is));

String fileName=br.readLine();
String st = System.getProperty("user.dir");
System.out.println(fileName);
File f=new File(st,fileName);

if(fileName == null) {
break;
}
/* 기록할 파일 연결함 */
FileOutputStream out=new FileOutputStream(f);

/* 보내온 파일의 끝까지 읽어서 파일로 씀 */

int i=0;
while((i=is.read())!=-1){
out.write((char)i);
}


System.out.println("저장됨!");
br.close(); is.close(); out.close();
}

/* 자원정리
br.close(); is.close(); out.close(); s.close(); ss.close();
br=null; is=null; out=null; s=null; ss=null;
*/
}
}

=> 서버

저는 파일을 지속적으로 계속 보내고 싶은데,,, 하나만 보내면 그 다음에서는 서버에서 받질 못하고 있어요 ㅠㅠㅠ
이문제 해결하고 싶은데 ㅜㅜㅜ 아직 초보자라서 해결 하기 힘드네요 ㅠㅠ
도와주세요 ㅠㅠ 여러분 ㅠㅠㅠ

익명 사용자의 이미지

1. 직접 짠 코드인가요? 올린 코드를 얼마나 이해하고 있나요?

2. 간단한 코드로 파일 전송을 구현할 수 있었던 이유는 프로토콜 자체가 간단했기 때문이죠.

클라이언트는 파일을 전부 보낸 후 소켓을 닫아버리고, 서버는 소켓이 닫힐 때까지 읽어서 저장하니까요.

위와 같은 상황에서 서버가 파일 여러 개를 받을 수 있게 만드는 방법은 크게 두 가지가 있습니다.

1) 파일을 다 받고 소켓이 닫힌 뒤, 서버가 다시 listen하게 만들면 됩니다.

클라이언트는 파일 전송을 마친 후 다음 파일을 전송하기 위해 새로 connect해야 합니다.

https://jdm.kr/blog/154 에 있는 "간단한 동기 소켓 서버" 코드를 참조하시길. 서버 소켓 생성이 루프에 감싸여 있는 것이 포인트입니다.

아주 우아하진 않지만 간단하게 구현 가능하죠. 위 링크에 있는 "스레드풀 소켓 서버"도 같이 봐 두면 좋겠네요.

2) 파일을 다 받더라도 소켓이 닫히지 않게 하면 됩니다.

이 경우 파일 전송이 완료되었음을 서버에게 알릴 다른 방법이 필요합니다. 뭐 예컨대

i. 애초에 클라이언트가 서버에게 파일 크기를 미리 알려주거나
ii. 적절한 프로토콜을 설계해서 클라이언트가 서버에게 "파일 데이터"와 구분되는 "파일 끝 신호"를 줄 수 있게 하면 됩니다.

이러면 서버는 파일 하나를 다 받을 때마다 다음 파일의 이름을 기다리고, 새 파일을 받을 수 있게 되죠.
클라이언트 역시 같은 소켓으로 계속 다음 파일을 주면 되고요.

익명 사용자의 이미지

서버 소켓 생성이 루프에 감싸여 있는 것이 포인트입니다.

=> 서버 소켓 accept이 루프에 감싸여 있는 것이 포인트입니다.

글쓴이의 이미지

진짜 ㅠㅠㅠㅠㅠㅠㅠㅠ 공부하는 중이라 연구하고 있는데 진짜 고마워요 ㅠㅠㅠㅠㅠ 한반 해보고 다시 글 올려도 괜찮겠죠?? ㅠㅠ 감사합니다 정말루 ㅠㅠ

김정균의 이미지

질문을 하실 때는 ㅠㅠㅠㅠ 이런 표현은 삼가시는 것이 좋습니다
급해요. 도와주세요.. 이런 문구도 도움이 안됩니다. 안되는 증상을 제목에 요약 하세요.
제목만 보고 스킵하는 답변자들도 수두룩 합니다.

그리고, 코드 입력시에는 code block 을 이용하세요. 글 작성 시에 작성 폼 상단에도, textarea 에도 안내를 하고 있습니다. 관심 좀 가져 주세요.

댓글 달기

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