Nio多线程CS收发信息问题(问题已经解决)

刚开始研究Java的NIO,就碰上了个问题,现在服务器端和客户段一个发一个收没有问题,但要是客户端和服务器段同时发收就有问题(我说的是双向的意思),这是为什么呢?相不明白,大家帮看看。
服务器端代码:

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package niocs.newpackage.service;

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.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import javax.swing.JTextPane;
import niocs.NIOCSView;
import niocs.newpackage.service.If.IServerConnect;

/**
*
* @author Administrator
*/
public class SetUpServer implements Runnable,IServerConnect
{
private final static int MAXACCEPT = 2048;
private NIOCSView serverShow;
private ByteBuffer w_Buff = ByteBuffer.allocate(MAXACCEPT);
private final static String ENTER = "\r\n";
private int port;
private JTextPane messageContent;
private StringBuilder message = new StringBuilder();
private String fMessage = null;
public SetUpServer(NIOCSView server)
{
this.serverShow = server;
setUPServer();
}

private void setUPServer()
{
try
{
messageContent = this.serverShow.getContent();
message.append("正在初始化端口");
message.append(ENTER);
messageContent.setText(message.toString());
port = Integer.parseInt(this.serverShow.getPort().getModel().getValue().toString());
message.append("初始化端口成功!");
message.append(ENTER);
messageContent.setText(message.toString());
}
catch(ClassCastException e)
{
port = 0;
message.append("端口初始化失败!");
message.append(ENTER);
messageContent.setText(message.toString());
}
}

public void run()
{
try
{

ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.configureBlocking(false);
Selector s = Selector.open();
ssc.socket().bind(new InetSocketAddress(port));
showMessage("系统正在建立对" + port + "端口的监听");
ssc.register(s,SelectionKey.OP_ACCEPT);
showMessage("系统已经启动!");
while(true)
{
int n = s.select();
if(n == 0)
{
continue;
}
Iterator it = s.selectedKeys().iterator();
while(it.hasNext())
{
SelectionKey key = (SelectionKey) it.next();
it.remove();
if(key.isAcceptable())
{
showMessage("有人连接到服务器.");
ServerSocketChannel server = (ServerSocketChannel) key.channel();
SocketChannel sc = server.accept();
showMessage("接受此连接请求");
sc.configureBlocking(false);

sc.register(s, SelectionKey.OP_READ);
}
if(key.isReadable())
{
SocketChannel sc = (SocketChannel)key.channel();
showMessage("正在读取数据");
if(!readData(sc))
{
key.cancel();
break;
}
sc.configureBlocking(false);

sc.register(s, SelectionKey.OP_WRITE);
}
if(key.isWritable())
{
SocketChannel sc = (SocketChannel)key.channel();
showMessage("向客户端发送数据");
fMessage = "123456";
if(!writeData(sc, fMessage))
{
key.cancel();
break;
}
sc.configureBlocking(false);

sc.register(s, SelectionKey.OP_READ);
}
}
}
}
catch(IOException e)
{
e.printStackTrace();
showMessage("读取时出错");
return;
}
}
private void showMessage(String aMessage)
{
message.append(aMessage);
message.append(ENTER);
messageContent.setText(message.toString());
}
private boolean readData(SocketChannel sc) throws IOException
{
ByteBuffer r_Buff = ByteBuffer.allocate(MAXACCEPT);
try
{

r_Buff.clear();

while(sc.read(r_Buff) > 0)
{
r_Buff.flip();
fMessage = new String(r_Buff.array()).trim();
showMessage("收的数据是:" + fMessage);
}
r_Buff = null;
return true;
}
catch(IOException e)
{
System.err.println("又报错了");
r_Buff.clear();
r_Buff.clear();
return false;
}
catch(NullPointerException e)
{
System.err.println("丫的出来空指针了");
return false;
}
}
private boolean writeData(SocketChannel sc,String message)
{
try
{
w_Buff.clear();
w_Buff.put(message.getBytes());
w_Buff.flip();
while(w_Buff.hasRemaining())
sc.write(w_Buff);
w_Buff.clear();
return true;
}
catch(IOException e)
{
System.err.println("sever已");
return false;
}
catch(NullPointerException e)
{
System.err.println("过去了都.");
return false;
}
}

public int getConnectPort()
{
return port;
}
}

这段代码实现了,接收和发送,即:服务器段受到什么就再返还给客户端。
客户端:线程1读线程

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package nioclien.backClass;

import java.io.IOException;
import java.net.ConnectException;
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.JTextArea;
import nioclien.JSendMessage;
/**
*
* @author Administrator
*/
public class ClienReadServer implements Runnable{
private final static int MAXSIZE = 2048;
private final static String ENTER = "\r\n";
private ByteBuffer w_Buff = ByteBuffer.allocate(MAXSIZE);
private static String host;
private int port;
private JSendMessage sender;
private StringBuilder message = new StringBuilder();
private JTextArea messageReciver;

public ClienReadServer(JSendMessage sender)
{
this.sender = sender;
messageReciver = sender.getReceiveText();
initForm();
}
private void initForm()
{
try
{
port = Integer.parseInt(this.sender.getPort().getText());
host = this.sender.getIPText().getText();
}
catch(NumberFormatException e)
{
port = 0;
message.append("初始化端口失败");
message.append(ENTER);
messageReciver.setText(message.toString());

}
}
@SuppressWarnings({"static-access", "empty-statement"})
public void run()
{
if(host.trim().startsWith("."))
{
this.sender.getConnectMenuItem().setEnabled(true);
return;
}
try
{
SocketChannel channel = SocketChannel.open(new InetSocketAddress(host, port));
channel.configureBlocking(false);

Selector selector = Selector.open();
SelectionKey skey = channel.register(selector, SelectionKey.OP_READ);

showMessage("与" + host + "已经成功连接,您现在可以发送消息了.");
boolean stop = false;
int n = 0;
int read = 0;
while(!stop)
{
n = selector.select();
if(n > 0)
{
Set set = selector.selectedKeys();
Iterator it = set.iterator();
while(it.hasNext())
{
skey = (SelectionKey) it.next();
it.remove();
if(skey.isReadable())
{
SocketChannel sc = (SocketChannel) skey.channel();
readServer(sc);
}
}
}
}
}
catch(ConnectException e)
{
this.sender.getConnectMenuItem().setEnabled(true);
System.err.println("连接服务器失败.");
return;
}
catch(IOException e)
{
e.printStackTrace();
}
}
@SuppressWarnings("empty-statement")
public void readServer(SocketChannel sc) throws IOException
{
try
{
ByteBuffer r_Buff = ByteBuffer.allocate(MAXSIZE);
r_Buff.clear();
while(sc.read(r_Buff) > 0)
{
r_Buff.flip();
showMessage("收的数据是:" + new String(r_Buff.array()).trim());
}
}
catch(NullPointerException e)
{
System.err.println("时间上的问题.");
}
}

private void showMessage(String aMessage)
{
message.append(aMessage);
message.append(ENTER);
messageReciver.setText(message.toString());
}

}

客户端线程2:写线程,向服务器端发送信息。

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package nioclien.backClass;

import java.io.IOException;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.LinkedList;
import javax.swing.JTextArea;
import nioclien.JSendMessage;

/**
*
* @author Administrator
*/
public class ClienServer implements Runnable
{
private SocketChannel sc;
private final static int MAXSIZE = 2048;
private final static String ENTER = "\r\n";
private ByteBuffer w_Buff = ByteBuffer.allocate(MAXSIZE);
private static String host;
private int port;
private JSendMessage sender;
private StringBuilder message = new StringBuilder();
private FQueue<String> fQueue = new FQueue<String>();

public ClienServer(JSendMessage sender)
{
this.sender = sender;
initForm();
}
private void initForm()
{
try
{
port = Integer.parseInt(this.sender.getPort().getText());
host = this.sender.getIPText().getText();
}
catch(NumberFormatException e)
{
port = 0;
message.append("初始化端口失败");
message.append(ENTER);

}
}
@SuppressWarnings({"static-access", "empty-statement"})
public void run()
{
if(host.trim().startsWith("."))
{
return;
}
try
{
InetSocketAddress addr = new InetSocketAddress(host, port);
sc = SocketChannel.open();
sc.connect(addr);

while(!sc.finishConnect());//等待建立连接
while(true)
{
try
{
synchronized(fQueue)
{
if(!fQueue.isEmpty())
{
String temp = fQueue.get();
System.out.println("要发送的数据是:" + temp);
w_Buff.clear();
w_Buff.put(temp.getBytes());
w_Buff.flip();
while(w_Buff.hasRemaining())
sc.write(w_Buff);
w_Buff.clear();
}
}
}
catch(Exception e)
{
System.err.print("丫的没发送成功");

}
Thread.currentThread().sleep(1000);
}
}
catch(ConnectException e)
{
this.sender.getConnectMenuItem().setEnabled(true);
System.err.println("连接服务器失败.");
return;
}
catch(IOException e)
{
e.printStackTrace();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}

public void sendMessage(String aMessage)
{
fQueue.put(aMessage);
}
private class FQueue<T>
{
private LinkedList<T> flist = new LinkedList<T>();

public void put(T o)
{
flist.addLast(o);
}

public T get()
{
return flist.removeFirst();
}

public boolean isEmpty()
{
return flist.isEmpty();
}
}

}

不知道为什么当写线程向服务器发出信息后,服务器又返还信息,客户端读线程好象并没有接收到。这是为什么呢?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值