Hỏi về Socket - TCP, mong mọi người giúp đỡ.

Discussion in 'Xây dựng ứng dụng server-client desktop' started by LostOdyssey, 4/1/13.

  1. LostOdyssey New Member

    Em đang tập làm 1 bài tập sử dụng Socket TCP để gửi 1 chuỗi từ Client lên Server và Server sẽ gửi trả lại chuỗi ký tự in hoa, e có làm thêm 1 giao diện Frame và tạo event cho các nút bấm, nhưng chỉ gửi lên Server và nhận kết quả trả về dc 1 lần, còn chạy đến lần thứ 2 thì chương trình treo, em mới tự học java còn kém mong mọi người giúp đỡ, em cảm ơn.
    Đây là code bên Client
    Code:
    import java.io.*;
    import java.net.*;
    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    
    public class MyFrame {
        public static void main(String args[]) throws IOException, UnknownHostException {
            @SuppressWarnings("unused")
            gui g = new gui("My Gui");
        }
    }
    class mySocket {
        private Socket sClient = null;
        private InputStream inp = null;
        private OutputStream outp = null;
        public String uperSocket(String string) throws IOException, UnknownHostException {
        String s = string;
        sClient = new Socket("localhost",8888);
        inp =  sClient.getInputStream();
        outp = sClient.getOutputStream();
        byte[] b = new byte[256];
        b = s.getBytes();
        outp.write(b);
        b = new byte[256];
        inp.read(b);
        s = new String(b).trim();
        return s;
        }
        public void closeSocket()throws IOException, UnknownHostException{
        inp = null;
        outp = null;
        sClient.close();
        }
    }
    class gui extends JFrame implements ActionListener {
        private mySocket mS = new mySocket();
        private static final long serialVersionUID = 1L;
        private JTextField txta = new JTextField();
        private TextArea ta = new TextArea();
        private JButton b;
        Container container = getContentPane();
        public gui(String title) {
            setTitle(title);
            setSize(400,300);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setLocationRelativeTo(null);
            setLayout(null);
            final JLabel label1 = new JLabel("Chuoi ky tu nhap vao");
            label1.setBounds(10,30,280,27);
            label1.setForeground(Color.BLUE);
            label1.setBackground(Color.GREEN);
            add(label1);
            txta.setBounds(10,60,280,27);
            add(txta);
            ta.setBounds(10,120,280,100);
            ta.setEditable(false);
            add(ta);
            b = new JButton("Start");
            b.setBounds(300,60,70,25);
            add(b);
            b.addActionListener(this);
            setVisible(true);
            setResizable(false);
    
            addWindowListener(new WindowAdapter() {
                    public void windowClosing(WindowEvent e)
                    {
                        try {
                            mS.uperSocket("CloseClientSocket");
                            mS.closeSocket();
                            System.exit(0);
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }
                    }
                    });
                }
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                JButton bt = (JButton) e.getSource();
                if(bt == b)
                {
                    String sTxta = txta.getText();
                    try {
                            String tA = mS.uperSocket(sTxta);
                            ta.setText(tA);
                    } catch (IOException e1) {
                            e1.printStackTrace();
                    }
                }
            }
    }
    Còn đây là code bên Server
    Code:
    import java.io.*;
    import java.net.*;
    
    public class bTCPServer {
        @SuppressWarnings("resource")
        public static void main(String args[]) throws IOException, UnknownHostException {
            ServerSocket svr = null;
            svr = new ServerSocket(8888);
            Socket sClient = null;
            sClient = svr.accept();
            InputStream inp = null;
            OutputStream outp = null;
            inp = sClient.getInputStream();
            outp = sClient.getOutputStream();
            byte[] b = null;
            while(true)
            {
                b = new byte[256];
                inp.read(b);
                String s = new String(b).trim();
                if(s.equals("CloseClientSocket")){
                    inp.close();
                    outp.close();
                    sClient.close();
                    break;
                }
                s = s.toUpperCase();
                b = new byte[256];
                b = s.getBytes();
                outp.write(b);
            }
        }
    }
    
    Cho em hỏi luôn là sao trong sự kiện CloseWindow nếu k cho 1 thông báo lên Server thì k thể tắt cửa sổ ngay lúc vừa bật lên mà sẽ bị EventException :
    Code:
    addWindowListener(new WindowAdapter() {
                    public void windowClosing(WindowEvent e)
                    {
                        try {
                            mS.uperSocket("CloseClientSocket"); // Nếu không thêm hành động này khi vừa bật cửa sổ mà tắt luôn sẽ văng EventException
                            mS.sClient.close();
                            System.exit(0);
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }
                    }
            });

    Attached Files:

  2. LostOdyssey New Member

    mọi người giúp em với :D
  3. monday0rsunday Active Member

    Có lỗi gì cụ thể thì bạn post ra nhé
    Khi close socket, bạn phải close các stream kèm theo, chứ ko phải gán null cho nó.
    inp = null;
    outp = null;
    Theo javadoc của j2se thì khi bạn close socket, các stream cũng tự động close theo, tuy nhiên bạn nên tự close stream (có khả năng 1 số bản java khác ko close nó sẽ lỗi, như của bên blackberry)
    (Thêm vào đó là code swing nên chạy trong EventDispatchThread, cái này là ngoài lề)

    Còn nguyên nhân tại sao bạn chỉ up được 1 lần, là do bạn code ko đúng thôi.
    Trong uperSocket, bạn khởi tạo mới socket ..., nghĩa là mỗi lần gọi hàm này, là 1 lần bạn gọi kết nối tới server
    Về phía server, bạn chỉ có duy nhất 1 chỗ accept socket client, nghĩa là, bạn chỉ cho phép 1 socket client kết nối, kết nối xong server stop luôn!!!.
    Cách sửa thì
    1 là bạn sửa code, cho socket client khởi tạo 1 lần thôi
    2 là bạn sửa code, sao cho server chạy "mãi mãi", mỗi lần vòng lặp mới nó sẽ chờ client kết nối. Cái này đơn giản là đưa tất cả đoạn code accept ... vào while(true) thôi
    cnf_cntt, LostOdyssey and mr vien like this.
  4. Joe Moderator

    Hi Odyssey.
    Gosh! I don't think your Client-Server package works. Reason is your bTCPServer may miss the request invoked within your windowClosing. Let me tell you how a server works: A server always waits for a client, regardless when a client comes and goes -like a shop. It must open the whole day and waits for "clients".
    In your case, the bTCPServer waits for ONE client.
    Why? The code sClient = svr.accept(); tells the server to catch an event and ...dies. Therefore you bumped against a wall:)
    How to avoid? You separate your bTCPServer code and create a new class. For example:
    Code:
    // bTCPServer
    while (true) {
      (new Xecute(srv.accept())).start();
    }
    
    Code:
    // the processing part of your bTCPServer.
    public class Xecute extends Thread {
        public Xecute(Socket soc) {
          this.soc = soc;
        }
        protected Socket soc;
        public void run() {
            InputStream inp = soc.getInputStream();
        ...
        }
    }
    
    LostOdyssey likes this.
  5. LostOdyssey New Member

    hehe, cảm ơn bạn, bài này mình bí đến mấy hôm sau khi hỏi ntin hỏi bạn rồi cũng tự sửa dc, mình sửa theo cách thứ 2, sửa kiểu đấy cũng đúng ý và mục đích bài code này của mình hơn :D
  6. LostOdyssey New Member

    thank you, you used thread but i just learn that skill in next lesson. i also used thread and it worked but i don't want use thread so i think a different way, finally it work :D thanks for reading my problem and give me a suggest.
  7. Joe Moderator

    Well, LostOdyssey. No offence. Then you don't understand the principle of Client-Server. A server MUST always ready for an unexpected incoming event and processes it as quickly as it can before it restarts to wait for the next event. Any delay may cause intermittent troubles that could be very hard or impossible to debug.
    It's like a baby who tries to run before it starts to crawl...:)
    LostOdyssey likes this.
  8. monday0rsunday Active Member

    @Joe: mình đồng ý là "server MUST always ready for an unexpected incoming event", nhưng "processes it as quickly as it can before it restarts to wait for the next event. Any delay may cause intermittent troubles that could be very hard or impossible to debug" chưa chắc đã cần thiết. Nó TÙY vào cách thực hiện của server.
  9. Joe Moderator

    Well, whatever you say :) as a former SUN senior developer I was partly responsible for the net-package....and I know that most servers intercept incoming request, kick off a processing task (thread) then wait for the next incoming event. Therefore I want to share my knowledge with you. Of course, there's no strict rule for a server. Hence, you're right: Nó TÙY vào cách thực hiện của server. ;)
    LostOdyssey likes this.
  10. tuyendt6 New Member

    chào bạn hiền!
    tớ hỏi một câu bài cậu post lên có phải cậu tham khảo trong quyển java tập 2 của phương lan không.tớ mới phát triển ứng dụng chat giữa server và client đấy,cậu cần thì pm tớ nhé,tớ send cho :D.và tớ có 1 lưu ý thế này nhé.khi cậu đã biết cậu gửi chuỗi kí tự rồi thì cậu cứ dùng Buffereader và Printwriter ấy.khi mà cậu không biết kiểu dữ liệu gửi đi là j cậu hãy dùng FileoutputStream và FileinputStream nhé :D.thực ra tớ thấy cậu viết rất dài dòng nên ngại đọc nhưng lập trình socket cũng đơn giản thôi bạn ạ.cơ chế của nó là thế này nhé :
    bên server :
    tạo 1 ServerSocket ss;
    đón Socket bên client chuyển sang thông qua ss.accept;
    tạo 1 đầu in,1 đầu out để nhận và gửi dữ liệu(nếu biết chắc là kiểu kí tự bạn cứ sử dụng Bufereder và PrintWriter) nếu chưa chắc chắn đc kiểu dữ liệu bạn mới dùng Fileoutput và Fileinput nhé;
    sau khi tạo dc đầu nhận rồi bạn chỉ việc gửi ,xử lý và nhận dữ liệu thôi
    gửi :
    out.println("String cần gửi");
    nhận:
    String masage=in.Readln();
    đó bạn cứ làm thử xem.phần mềm chát của mình phát triển cũng hay lắm.nếu bạn muốn tham khảo mình gửi cho nhé
    mở rộng lên bạn có thể gửi dc file đấy :D
    thân!
    LostOdyssey likes this.
  11. Joe Moderator

    Hi Tuyendt,
    if you address me...I'm truly sorry that I don't understand what you wrote. And what's the heck with FileInput- and FileOutputStream?
  12. monday0rsunday Active Member

    The person tuyendt refered to is LostOdyssey.
    tớ = mình= I
    cậu = bạn = you
    bạn hiền ~ close friend, buddy...
    Vietnamese is complicated, especially written vietnamese of teenage.
    Joe likes this.
  13. Joe Moderator

    Gosh! How ghoulish. My girlfriend taught me:
    toi = I to a strange
    anh = I to a younger man or YOU to a strange (same age or older)
    em = I to an older man or YOU to a young strange
    cau = a bridge
    to = big
    minh = body
    ban = friend
    hien? don't know
    I talked with her today and she just laughed like this=))
  14. tuyendt6 New Member

    dear Joe!
    where are you from?
    i am vietnames.ofcorse i reply by vietnames,if you want to understand,you must learn Vietnamese.i have a project Chat ym.if you want to consult.i'll share for you!
  15. Joe Moderator

    Hello Tuyendt,
    I'm from San Diego-California, a Franco-German origin. Well, I must not learn anything;) I learn Vietnamese because I'm hopelessly falling in love with a Vietnamese American girl...
    Chat? Consulting? Well, NO fee just because of you :D if I can spare time for you. OK?
  16. monday0rsunday Active Member

    :))
    1. You(and maybe your gf) 've written vietnamese without marked, that sometimes causes misunderstanding.
    In vietnamese, tớ (I) # to (big), cậu (younger brother of mother, or "you" when you said to your friend) # cầu (bridge) # câu (sentence)
    2. A word can have multiple meanings (homonym), e.g. mình (body) # mình (I)
    3. There isn't any keyboard for vietnamese , so writing vietnamese need vietnamese IME e.g. unikey (as far as I know). That sometimes is not convenient (especially before 1991, when there wasn't any vietnamese IME :)) ), and people write vietnamese without marked, e.g, "tớ" replaced by "to", "cậu/cầu" replaced by "cau"
  17. Joe Moderator

    Morning my friend mondayOrsunday,
    my 'gf' confirmed what you wrote. That's the reason I've lots of troubles to speak and write Vietnamese. I was in HCM City (2010) and people always amazed then =))at me when I opened my mouth and tried to utter some Vietnamese words...
    khangphamngoc90 likes this.
  18. LostOdyssey New Member

    vậy bạn gửi vào mail haibx.105@gmail.com cho t nhé, cảm ơn nhiều, còn bài trên thầy t dạy lý thuyết về socket với vài cái ví dụ nhỏ rồi t về tự code thôi chứ k đọc sách j cả, mà t thấy dùng thread có vẻ đúng nhất :D, sách hay thì bạn gửi luôn t nhé :D
    cho t hỏi luôn là có thể chồng 2 cái JPanel lên nhau k, t chồng thử thì k dc, t post code bạn xem hộ t nhé, ngắn thôi, test mà :D cái panel1 nó k nằm đúng vị trí mong muốn trong cái wholePanel ấy.
    Code:
    import java.awt.*;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class TestPanel extends JFrame {
        TestPanel(String title) {
            super(title);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setSize(600,600);
            setLocationRelativeTo(null);
            setVisible(true);
            setResizable(false);
        }
        public static void main(String[] args) {
            TestPanel myGui = new TestPanel("My Gui");
            Dimension d;
            d = myGui.getSize();
    
            JPanel wholePanel = new JPanel();
            wholePanel.setSize(d.height,d.width);
            wholePanel.setBackground(Color.yellow);
            myGui.add(wholePanel);
    
            JPanel panel1 = new JPanel();
            panel1.setSize(new Dimension(100,100));
            panel1.setBackground(Color.blue);
            panel1.setLocation(100,100);
            wholePanel.add(panel1);
        }
    }
  19. Joe Moderator

    Hi LostOdyssey,
    Oh... Should I send you my manuscript? Well, as a private docent I do lecture Computer Science... And if you want to know more about Threading, Client-Server concept I would be happy to extend my thread "A programming language? JAVA? Tuning?" and discuss a bit more about the concept of Threading and Client-Server.

    However, for the sake of the whole CongdongJava community I prefer to post here... BUT I don't know how "big" my thread is allowed to grow...and if Admin JackV and Moderator Nancru let me do that.
    Joe

    PS. The posted TestPanel is well done. In one word: Superb.
    khangphamngoc90 likes this.
  20. LostOdyssey New Member

    docent means document ? If you can share it with me, it'll be great, thank you. There is a problem in my test, I can't setSize and setLocation as i want for panel1. I'm not sure can I add a panel on a panel.
    I've known about rmi and I feel it's interesting :D

Chia sẻ trang này



Ve may bay di Ha Noi | Ve may bay di Vinh | Ve may bay di Hue | Ve may bay di Da Nang | Ve may bay di Nha Trang | Ve may bay di Da Lat | Ve may bay di Phu Quoc | Ve may bay di Sai Gon | Ve may bay di TPHCM | Ve may bay di Buon Me Thuot | Ve may bay di Hai Phong | Ve may bay di Dong Hoi | Ve may bay Vietjet Air | Phong ve may bay Vietjet Air | Ve may bay Vietnam Airlines | Phong ve may bay Vietnam Airlines | Ve may bay Vietnam Airlines | Ve may bay gia re | Ve may bay | Mua ve may bay | Jetstar | Vietnam Airlines | Air Asia | Tiger Airways | Ve may bay di My | Vietjet Air | Ve may bay di Ha Noi | Ve may bay di Da Nang | Ve may bay di Hai Phong | Ve may bay di Vinh