자바 소켓 프로그래밍 파일전송 질문입니다.
한곳에 모으니 드럽게 기네요;;;
채팅프로그램인데 파일전송이랑 채팅이랑 같이 되는걸 구현하려고하는데요.
채팅은 잘되는 파일전송부분에서 파일 하나보내고 소켓닫는거는 잘 되는데
파일을 계속해서 보내고 싶은데 클라이언트에서는 계속보내는데 서버에서 파일 한번 받고
그것도 크기가 0바이트로 나오고 다음에 보내는 파일을 받아들이질 못하네요.
부탁드립니다. ㅠㅠ
////// server측 /////////
채팅 관련
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatS {
public static void main(String args[]){
System.out.println("자바 커뮤니티 채팅 서버 v1.0");
ServerSocket ss = null;
Vector v =null;
try {
//9000번 포트를 사용하는 서버 소켓을 생성한다.
ss = new ServerSocket(9000);
v = new Vector(10);
while(true){
//클라이언트로부터 접속 요청이 발생하면 서버와 클라이언트
// 사이에 새로운 소켓을 생성한다.
Socket c = ss.accept();
// accept() 메소드가 한번 실행된이후로
// 새로운 소켓이 올때까지 대기하므로 아래 문장도 accept()가 실행될때까지 기다린다.
//클라이언트의 정보를 저장하는 ClientInfo 클래스를 생성하고
// 벡터 객체를 저장한다.
ClientInfo ci = new ClientInfo(c);
v.add(ci); // 새로운 클라이언트가 접속할때마다 벡터에 저장한다.
//각 소켓(클라이언트 하나당 소켓 하나 생성)에 대한 작업을 수행할 쓰레드를 생성한다.
ChatThread ct = new ChatThread(c,v);
Thread t = new Thread(ct);
t.start();
System.out.println(ci.getIP() +"가 접속했습니다.");
}
}catch(Exception e){
try{
// 서버 소켓에 예외가 발생하면 소켓을 닫고 프로그램을 종료한다.
ss.close();
System.exit(0);
}catch(Exception ie){
}
}
}
}
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatThread implements Runnable {
private Socket c = null;
private BufferedReader br = null;
private Vector v = null;
private File file;
private InputStream is;
public ChatThread(Socket c, Vector v){
this.c = c;
this.v = v;
// 클라이언트로부터 전송된 내용을 읽어오기 위한 입력 스트림을 생성한다.
try{
InputStream is = c.getInputStream();
br = new BufferedReader ( new InputStreamReader(is));
} catch (Exception e){
}
}
public void run(){
while(true){
String str = null;
int j =0;
try{
// 클라이언트로부터 문자열을 읽어온다.
// 클라이언트로부터 파일을 읽어온다.
str = br.readLine();
}catch(Exception e){
break;
}
for(int i = 0 ; i
// 읽어온 문자열을 백터객체에 저장된 각 클라이언트에 전송한다.
ClientInfo ci = (ClientInfo)v.get(i);
ci.write(str); // ClientInfo 클래스의 write 메소드 사용
}
}
try{
//예외가 발생하여 while
// 루프가 종료되면 스트림과 소켓을 닫는다.
br.close();
c.close();
} catch(Exception e) {
}
}
}
import java.io.*;
import java.net.*;
import java.util.*;
public class ClientInfo { // 서버에서 클라이언트 정보를 가져와서 저장한다.
private Socket c;
private String ip;
private BufferedWriter bw;
public ClientInfo(Socket c){
this.c = c;
// 소켓을 연결한 클라이언트의
// 아이피 정보를 저장한다.
ip = c.getInetAddress().getHostAddress();
//
// 클라이언트에 문자열을 전송하기 위한 출력 스트림을 생성한다.
try{
bw = new BufferedWriter (new OutputStreamWriter(c.getOutputStream()));
} catch (Exception e){
}
}
public boolean write(String str){
// 인자로 받은 문자열을 출력 스트림을 사용하여 전송한다.
try{
bw.write(str+"\n");
bw.flush();
}catch(Exception e) {
return false;
}
return true;
}
public String getIP(){
return ip;
}
}
// 파일 관련//
import java.io.*;
import java.net.*;
import java.util.*;
public class FileS {
public static void main(String[] args) {
ServerSocket ss = null;
Socket c =null;
//클라이언트와 연결된 소켓들을 배열처럼 저장할 벡터객체 생성
Vector v =null;
try{
ss= new ServerSocket(9401);
v = new Vector(10);
while(true){
System.out.println("파일전송 접속대기중..");
c = ss.accept();
//클라이언트와 연결된 소켓을 벡터에 담기
ClientInfo ci = new ClientInfo(c);
v.add(ci);
FileThread ct = new FileThread(c,v);
Thread t = new Thread(ct);
t.start();
System.out.println(ci.getIP() +"가 접속했습니다.");
}
}catch(IOException ie){
System.out.println(ie.getMessage());
}
}
}
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.JOptionPane;
public class FileThread implements Runnable {
private Socket c = null;
private BufferedReader br = null;
private Vector v = null;
private File file;
private String fileName=null;
private FileOutputStream out;
private InputStream ins=null;
public FileThread(Socket c, Vector v){
this.c = c;
this.v = v;
// 클라이언트로부터 전송된 내용을 읽어오기 위한 입력 스트림을 생성한다.
try{
ins =c.getInputStream();
this.br = new BufferedReader ( new InputStreamReader(ins));
} catch (Exception e){
}
}
public void run(){
getFileInfo();
}
synchronized void getFileInfo(){
try{
// 클라이언트로부터 파일을 읽어온다.
fileName = br.readLine();
//int check = JOptionPane.showConfirmDialog(null,"파일을 수신하시겠습니까?","파일 전송 요청",JOptionPane.YES_NO_OPTION,JOptionPane.QUESTION_MESSAGE);
int size = Integer.parseInt(br.readLine());
System.out.println(size);
//if(check== 0){
System.out.println(file);
file= new File("c:\\3DP\\Net",fileName);
// 기록한 파일 연결함
out = new FileOutputStream(file);
// 보내온 파일의 끝까지 읽어서 파일로 씀
int temp =0;
byte[] buffer = new byte[1024];
for(int i=0; i
temp =ins.read(buffer);
if(temp==-1)
break;
System.out.println(buffer);
System.out.println(temp);
out.write(buffer);
}
file =null;
br=null; ins =null; out =null; c=null;
/*while((temp = ins.read(buffer))!=-1){
System.out.println(buffer);
//System.out.println(buffer);
out.write(buffer);
} */
//}
}catch(Exception ioe){
ioe.printStackTrace();
System.out.println("Server ReSource Clear");
try{br.close(); } catch(Exception e){ e.printStackTrace();}
try{ins.close(); } catch(Exception e){ e.printStackTrace();}
try{out.close(); } catch(Exception e){ e.printStackTrace();}
}
/* for(int i = 0 ; i
// 읽어온 문자열을 백터객체에 저장된 각 클라이언트에 전송한다.
ClientInfo ci = (ClientInfo)v.get(i);
//
ci.write(str); // ClientInfo 클래스의 write 메소드 사용
*/
}
}
///////////////////////////////////////////////////////////
//////// 클라이언트 ///////////
package Client;
import java.io.*;
import java.net.*;
public class ChatClient {
private Socket s = null;
private Socket sf = null;
private String ip = null;
private int port = 0;
private int portf =0;
private String name = null;
public static void main(String args[]){
ChatClient cc = new ChatClient();
cc.init(); // 초기화
}
public ChatClient(){
}
public void init(){
//채팅클라이언트 초기화
//서버의 주소와 포트 번호를 입력받는 다이얼로그
InputForm sif = new InputForm(this);
sif.setModal(true); // 현재 창이 종료되기전까지는 다음창을 실행못함.
sif.setVisible(true);
//sif.show(true);
// 채팅에서 사용할 이름을 입력받는 다이얼로그
NameInputform nif = new NameInputform(this);
nif.setModal(true);
nif.setVisible(true);
// 입력된 서버의 주소와 포트번호로 소켓을 생성한다.
try{
s = new Socket(ip ,port);
sf = new Socket("localhost" ,portf);
} catch(Exception e){
}
// 생성된 소켓과 채팅에서 사용할 이름을 인자로 새로운
// 채팅창 프레임을 생성한다.
ChatClientForm ccf = new ChatClientForm(s,sf,name);
ccf.setVisible(true);
//ccf.show(true);
}
//초기화 값을 멤버 벼수에 저장하는 set 메서드
public void setIp(String ip){
this.ip = ip;
}
public void setPort(int port){
this.port = port;
}
public void setPortf(int portf){
this.portf = portf;
}
public void setName(String name){
this.name = name;
}
}
package Client;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
//import sds.FileListenThread;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.Vector;
public class ChatClientForm extends JFrame implements ActionListener {
private Socket s;
private Socket sf;
private String name;
private BufferedWriter bw,bw1;
private DataInputStream dis;
private DataOutputStream dos;
private FileInputStream fis = null;
private OutputStreamWriter osw = null;
private JTextArea ta;
private JTextField tf;
private JButton b,b1,b2;
private JPanel p1,p2;
private Vector User; // 현재 사용하고 있는 채팅 멤버
private JFileChooser jfc = new JFileChooser("C://");
private JScrollPane jsp ;
private FileDialog fd;
//private FileListenThread flt;
private File file=null;
private String directory="";
public ChatClientForm(Socket s,Socket sf, String name)
{
this.s=s;
this.sf=sf;
this.name = name;
this.setTitle(name+"님의 채팅 클라이언트");
//////////////////////////////////////////
b1=new JButton("파일선택");
b1.addActionListener(this);
b2=new JButton("파일전송");
b2.addActionListener(this);
///////////////////////////////////
ta = new JTextArea();
jsp = new JScrollPane(ta);
ta.setEditable(false);
tf = new JTextField(25);
b = new JButton("전송");
b.addActionListener(this);
p1 = new JPanel();
p1.add(tf);
p1.add(b);
p1.add(b1);
p1.add(b2);
jsp.setWheelScrollingEnabled(true);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(p1,"South");
getContentPane().add(jsp,"Center");
setBounds(200,200,600,300);
try{
//서버로부터 문자열을 수신하기 위한 쓰레드를 생성한다.
ListenThread lt = new ListenThread(s,this);
Thread t = new Thread(lt);
t.start();
//FileListenThread flt = new FileListenThread(sf,this);
//Thread t1 = new Thread(flt);
//t1.start();
//서버에 문자열을 송신하기 위한 출력 스트림을 생성한다.
bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
}catch(Exception e){
}
}
public void writerTextArea(String str){
ta.append(str +"\n");
}
public void actionPerformed(ActionEvent ae){
if(ae.getSource()==b)
try{
//버튼이 클릭되면 텍스트 필드의 내용을 서버에 송신한다.
bw.write(name+" : " +tf.getText() +"\n");
bw.flush();
tf.setText("");
}catch(Exception e){
//서버에 문자열을 송신할수 없으면 스트림과 소켓을 닫고
// 프로그램을 종료한다.
try{
bw.close();
s.close();
}catch(Exception e2){
System.exit(0);
}
}
finally{
System.out.println("채팅 소켓은 닫혔는가?"+s.isClosed());
}
if(ae.getSource()==b1){
try{
jfc.setDialogTitle("전송할파일");
//jfc.setMultiSelectionEnabled(true); ///다중선택 가능하게 만들기
jfc.showSaveDialog(this);
file= jfc.getSelectedFile();
tf.setText(file.getAbsolutePath());
}catch(Exception e){
try{
System.out.println("소켓이 닫혔습니다.");
}catch(Exception e2){
}
}
}
if(ae.getSource()==b2){
// 파일전송
try{
//버튼이 클릭되면 텍스트 필드의 내용을 서버에 송신한다.
osw = new OutputStreamWriter(sf.getOutputStream());
bw1 = new BufferedWriter(osw);
bw1.write(file.getName()+"\n");
bw1.flush();
byte[] buffer = new byte[1024];
System.out.println(file.length()+ "\n" + file.getTotalSpace());
int size = (int)(file.length()/buffer.length);
if(file.length()%buffer.length!=0){
size++;
}
System.out.println(size);
osw = new OutputStreamWriter(sf.getOutputStream());
bw1 = new BufferedWriter(osw);
bw1.write(size+"\n");
bw1.flush();
fis = new FileInputStream(file);
dis = new DataInputStream(fis);
dos = new DataOutputStream(sf.getOutputStream());
//1k씩 보냅니다.
System.out.println("에러1");
int len =0;
while((len = dis.read(buffer))!=-1){
//System.out.println(len);
System.out.println(buffer);
dos.write(buffer,0,len);
dos.flush();
}
file = null;
}catch(Exception e){
//서버에 문자열을 송신할수 없으면 스트림과 소켓을 닫고
// 프로그램을 종료한다.
try{
System.out.println("전송에 실패했습니다.");
if(osw!=null) osw.close();
if(bw1!=null) bw1.close();
if(fis!=null) fis.close();
if(dis!=null) dis.close();
if(dos!=null) dos.close();
//System.out.println("채팅 소켓은 닫혔는가?"+s.isClosed());
}catch(Exception e2){
System.exit(0);
}
}
finally{
System.out.println("채팅 소켓은 닫혔는가?"+sf.isClosed());
}
}
}
}
package Client;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
public class InputForm extends JDialog implements ActionListener {
private JLabel ipl;
private JLabel port1;
private JTextField iptf;
private JTextField porttf;
private JButton b;
private JPanel ipjp;
private JPanel portjp;
private JPanel bjp;
private ChatClient c;
public InputForm(ChatClient c){
setTitle("서버 정보 입력 다이얼로그");
this.c =c;
ipl = new JLabel( "I P : ");
port1 = new JLabel("port : ");
iptf = new JTextField(15);
porttf = new JTextField(15);
b = new JButton ("입 력");
b.addActionListener(this);
ipjp = new JPanel();
portjp = new JPanel();
bjp = new JPanel();
ipjp.add(ipl);
ipjp.add(iptf);
portjp.add(port1);
portjp.add(porttf);
bjp.add(b);
setBounds(100,100,240,130);
getContentPane().setLayout(new GridLayout(3,1));
getContentPane().add(ipjp);
getContentPane().add(portjp);
getContentPane().add(bjp);
}
public void actionPerformed (ActionEvent ae){
//입력된 서버의 정보를 다이얼로그를 호출하는 클래스의 멤버변수에 저장한다.
c.setIp(iptf.getText());
c.setPort(Integer.parseInt(porttf.getText()));
c.setPortf(9401);
setVisible(false); // 실행이 끝난후에 지워준다.
//show(false);
}
}
package Client;
import java.io.*;
import java.net.*;
public class ListenThread implements Runnable {
private Socket s;
private ChatClientForm f;
private BufferedReader br;
public ListenThread (Socket s, ChatClientForm f){
this.s =s;
this.f =f;
try{
//인자로 받은 소켓에 대한 입력 스트림을 만든다.
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
}catch(Exception e){
}
}
public void run(){
while(true){
//서버로부터 받은 내용을 읽어 클라이언트 텍스트 에어리어에 적는다.
try{
f.writerTextArea(br.readLine());
}catch(Exception e){
}
}
}
}
package Client;
import javax.swing.*;import javax.swing.event.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
public class NameInputform extends JDialog implements ActionListener {
private ChatClient c;
private JTextField jf;
private JButton jb;
private JPanel jp1;
private JPanel jp2;
public NameInputform(ChatClient c){
this.c =c;
setTitle("대화명을 입력하세요");
setBounds( 100,100,250, 70);
jf = new JTextField(15);
jb = new JButton ("입 력");
jb.addActionListener(this);
jp1 = new JPanel();
jp2 = new JPanel();
jp1.add(jf);
jp2.add(jb);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(jp1,"West");
getContentPane().add(jp2,"East");
}
public void actionPerformed ( ActionEvent ae){
//입력된 이름을 다이얼로그를 호출한 클래스의 멤버 변수에 저장한다.
c.setName(jf.getText());
setVisible(false);
}
}
댓글 달기