日期:2014-05-20  浏览次数:20972 次

想写一个聊天室的程序,关于数据传输的问题??
现在只写到客户端发一句话,服务器收到在发回给客户端,先客户端得到要发送的字节大小,先发给服务器,在发送实际数据。服务器先收到字节大小,然后准备一个对应大小的ByteBuffer来接收后面的数据,在把收到的字节大小跟数据发给客户端。客户端也跟服务器一样先接收字节大小,准备ByteBuffer接收,然后显示出来。

现在是服务器接收没有问题,但客户端接收有问题

Java code

//这里是客户端发送数据
                           String s = enter.getText();
            byte[] bs = s.getBytes();
            int i = bs.length;    
            len.clear();
            len.put(Parse.intToByte(i));
            len.flip();
            write = ByteBuffer.allocate(i);
            write.clear();
            write.put(s.getBytes());
            write.flip();
            try 
            {
                socket.write(len);
                socket.write(write);
            } 
            catch (IOException e1) 
            {
                e1.printStackTrace();
            }
            enter.setText("");
            write = null;



Java code

//服务器接收和发送数据
                        socket = (SocketChannel)key.channel();
                        len.clear();
                        socket.read(len);
                        len.flip();                        
                        int i = Parse.byteToInt(len.array());                        
                        read = ByteBuffer.allocate(i);
                        read.clear();
                        socket.read(read);
                        read.flip();
                        socket.write(len);
                        socket.write(read);
                        read = null;



Java code

//客户端接收数据,就这里出java.lang.OutOfMemoryError。有时候出有时候不出
                        readSocket = (SocketChannel)reader.attachment();
                        len.clear();
                        readSocket.read(len);
                        len.flip();
                        int i = Parse.byteToInt(len.array());
                                                       //不知道怎么回事他把len读了两次,
                                                       //第二次i的值就会很大,下面这句就报错,而且用debug跟就
                                                       //不报错。
                        read = ByteBuffer.allocate(i);
                        read.clear();
                        readSocket.read(read);
                        read.flip();
                        String s = new String(read.array());
                        show.append(s + "\n");
                        read = null;



是不是我写的有问题???

下面是全部的代码
Java code

server

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class Server 
{
    private Selector sel;
    private ServerSocketChannel server;
    private int port;
    private ByteBuffer len = ByteBuffer.allocate(4);
    private ByteBuffer read;
    
    public static void main(String[] args)
    {
        Server s = new Server(9999);
    }
    
    public Server(int port)
    {
        this.port = port;
        try 
        {
            sel = Selector.open();
            server = ServerSocketChannel.open();
            server.configureBlocking(false);
            server.socket().bind(new InetSocketAddress(this.port));
            server.register(sel, SelectionKey.OP_ACCEPT);
            System.out.println("服务器启动!");
    
            while(sel.select() > 0)
            {
                Set<SelectionKey> keys = sel.selectedKeys();
                Iterator<SelectionKey> its = keys.iterator();
                while(its.hasNext())
                {
                    SelectionKey key = its.next();
                    its.remove();
                    SocketChannel socket = null;
                    
                    if(key.isAcceptable())
                    {
                        ServerSocketChannel serverSocket = (ServerSocketChannel)key.channel();
                        socket = serverSocket.accept();
                        System.out.println("有一个用户连接!");
                        socket.configureBlocking(false);
                        SelectionKey sk = socket.register(sel, SelectionKey.OP_READ);                        
                    }
                    else if(key.isReadable())
                    {
                        socket = (SocketChannel)key.channel();
                        len.clear();
                        socket.read(len);
                        len.flip();                        
                        int i = Parse.byteToInt(len.array());                        
                        read = ByteBuffer.allocate(i);
                        read.clear();
                        socket.read(read);
                        read.flip();
                        socket.write(len);
                        socket.write(read);
                        read = null;
                    }
                        
                }
            }
        } 
        catch (ClosedChannelException e) 
        {
            e.printStackTrace();
        } 
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    }
    
    public void finalize()
    {
        
        try 
        {
            if(sel != null)
            {
                sel.close();
                sel = null;
            }    
            if(server != null)
            {
                server.close();
                server = null;
            }
        } 
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    }
}

client

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;

public class Client extends JFrame 
{
    
    JTextField enter;
    JTextArea show;
    JTextArea user;
    JLabel l;
    
    SocketChannel socket;
    Selector sel;
    ByteBuffer len = ByteBuffer.allocate(4);
    ByteBuffer write;
    ByteBuffer read;
    SelectionKey reader;
    boolean b = false;
    
    public static void main(String[] args) 
    {
        Client c = new Client();
                c.setVisible(true);    
                c.init();
                c.read();
        
    }
    
    public Client()
    {
        show = new JTextArea();
        show.setEditable(false);
        show.setBounds(0, 0, 560, 500);
        show.setBorder(new LineBorder(new Color(234, 201, 222)));
        l = new JLabel("输入内容");
        l.setBounds(0, 510, 60, 30);
        enter = new JTextField();
        enter.setBounds(60, 510, 500, 30);
        user = new JTextArea();
        user.setEditable(false);
        user.setBounds(562, 2, 128, 540);
        user.setBorder(new LineBorder(new Color(188, 230, 235)));
        this.setBounds(100, 50, 700, 570);    
        this.setLayout(null);
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        enter.addActionListener(new Monitor());
        this.add(show);
        this.add(l);
        this.add(enter);
        this.add(user);
        this.setResizable(false);
    }
    
    public void init()
    {
        try 
        {
            sel = Selector.open();
            socket = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9999));
            socket.configureBlocking(false);
            reader = socket.register(sel, SelectionKey.OP_READ);    
            reader.attach(socket);
            b = true;
        }
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    }
    
    public void read()
    {
        Set<SelectionKey> keys = null;
        
        try 
        {
            while(b)
            {
                sel.select();
                keys = sel.selectedKeys();
                Iterator<SelectionKey> its = keys.iterator();
                while(its.hasNext())
                {
                    SelectionKey key = its.next();
                    SocketChannel readSocket = null;
                    if(key.isReadable())
                    {
                        readSocket = (SocketChannel)reader.attachment();
                        len.clear();
                        readSocket.read(len);
                        len.flip();
                        int i = Parse.byteToInt(len.array());
                        read = ByteBuffer.allocate(i);
                        read.clear();
                        readSocket.read(read);
                        read.flip();
                        String s = new String(read.array());
                        show.append(s + "\n");
                        read = null;
                    }
                }
            }
        } 
        catch (IOException e) 
        {
            e.printStackTrace();
        }
    }

    private class Monitor implements ActionListener
    {

        @Override
        public void actionPerformed(ActionEvent e) 
        {
            String s = enter.getText();
            byte[] bs = s.getBytes();
            int i = bs.length;    
            len.clear();
            len.put(Parse.intToByte(i));
            len.flip();
            write = ByteBuffer.allocate(i);
            write.clear();
            write.put(s.getBytes());
            write.flip();
            try 
            {
                socket.write(len);
                socket.write(write);
            } 
            catch (IOException e1) 
            {
                e1.printStackTrace();
            }
            enter.setText("");
            write = null;
        }
        
    }
}