我自己占领1楼,发一下服务端代码:
服务端SocketTest.java如下:import java.net.* ;
import java.util.* ;
import java.io.* ;
public class SocketTest{
public static void main(String[]args){
time() ;
}
public static void time(){
long start = System.currentTimeMillis() ;
try{
ServerSocket serverS = new ServerSocket(9000) ; Socket incoming = serverS.accept();
try{
OutputStream outStream = incoming.getOutputStream();
InputStream inStream = incoming.getInputStream() ;
outStream.write("Hello ! Enter BYE to exit .".getBytes()) ;
outStream.write("\nme[c]:".getBytes());
outStream.flush(); Scanner clientSay = new Scanner(inStream) ;
boolean done = false ;
while(!done && clientSay.hasNextLine() ){
System.out.print("Client : ") ;
String line = clientSay.nextLine() ;
System.out.println(line) ;
if( line.trim().equals("BYE") ) //如果客户端说了“BYE”,则准备结束链接
{
String end = "Server:goodbye ..." ;
byte[] bye = end.getBytes();
outStream.write(bye);
done = true ; //跳出 while 的条件
}
else
{
System.out.print("我说 : ");
String serverStr = "me[s] : "+consoleRead(null)+"\n\rme[c] :";/*consoleRead返回:在控制台输入的语句*/
//byte[] serverSayBytes = (serverStr).getBytes();
outStream.write(serverStr.getBytes());
//outStream.flush();
System.out.println("......等待客户端回复...... :");
}
}// end while
}
finally{
incoming.close() ;
}
}
catch(Exception err){
err.printStackTrace() ;
}
long end = System.currentTimeMillis() ;
System.out.println("总共连接时间:"+(end-start)+"(ms)") ;
}
/**
* @param: 在输入控制台之前,控制台出现的提示语
* @return:在控制台输入的语句,以'!'、'!'、'\n'结束
*/
public static String consoleRead(String prompt/*输入控制台前,控制台的提示语*/)
throws IOException{
if( null != prompt )
System.out.println(prompt);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine() ;
return str ;
}
}
望各位不吝赐教!
服务端SocketTest.java如下:import java.net.* ;
import java.util.* ;
import java.io.* ;
public class SocketTest{
public static void main(String[]args){
time() ;
}
public static void time(){
long start = System.currentTimeMillis() ;
try{
ServerSocket serverS = new ServerSocket(9000) ; Socket incoming = serverS.accept();
try{
OutputStream outStream = incoming.getOutputStream();
InputStream inStream = incoming.getInputStream() ;
outStream.write("Hello ! Enter BYE to exit .".getBytes()) ;
outStream.write("\nme[c]:".getBytes());
outStream.flush(); Scanner clientSay = new Scanner(inStream) ;
boolean done = false ;
while(!done && clientSay.hasNextLine() ){
System.out.print("Client : ") ;
String line = clientSay.nextLine() ;
System.out.println(line) ;
if( line.trim().equals("BYE") ) //如果客户端说了“BYE”,则准备结束链接
{
String end = "Server:goodbye ..." ;
byte[] bye = end.getBytes();
outStream.write(bye);
done = true ; //跳出 while 的条件
}
else
{
System.out.print("我说 : ");
String serverStr = "me[s] : "+consoleRead(null)+"\n\rme[c] :";/*consoleRead返回:在控制台输入的语句*/
//byte[] serverSayBytes = (serverStr).getBytes();
outStream.write(serverStr.getBytes());
//outStream.flush();
System.out.println("......等待客户端回复...... :");
}
}// end while
}
finally{
incoming.close() ;
}
}
catch(Exception err){
err.printStackTrace() ;
}
long end = System.currentTimeMillis() ;
System.out.println("总共连接时间:"+(end-start)+"(ms)") ;
}
/**
* @param: 在输入控制台之前,控制台出现的提示语
* @return:在控制台输入的语句,以'!'、'!'、'\n'结束
*/
public static String consoleRead(String prompt/*输入控制台前,控制台的提示语*/)
throws IOException{
if( null != prompt )
System.out.println(prompt);
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = br.readLine() ;
return str ;
}
}
望各位不吝赐教!
解决方案 »
- 请帮忙看看出问题的地方应该怎么改
- 高级应用题
- 不知道在线编辑器的 [自动排版]功能怎么做!我看fck也没有这个功能!只有
- java针打不正常(急!急!急!)
- 如何覆盖的写文件?
- 关于java的包,我快晕死了,谁能给我一个明确的解释?
- 如何将JAVA程序做成EXE文件
- 紧急呼救:如何用java编制年月日星期?为什么只可以准确输出8个月,用泰勒公式不对吗?(在线等)
- 那里可以下载到 java virtual machine for win98 !
- 大神们进来交流一下如何快速的理解现有的代码
- 看不懂的Java递归
- 搭建Spring项目时报错,非常着急,弄了好几天了,没有进展,我是新手,希望大家批评指教指教
服务端import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;public class ServerTread extends Thread
{
private Socket socket;
public ServerTread(Socket socket)
{
this.socket = socket;
}
@Override
public void run()
{
try
{
InputStream is = socket.getInputStream();
while (true)
{
byte[] b = new byte[1024];
int length = is.read(b);
String str = new String(b,0,length);
System.out.println(str);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
客户端import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;public class ClientTread extends Thread
{
private Socket socket;
public ClientTread(Socket socket)
{
this.socket = socket;
}
@Override
public void run()
{
try
{
OutputStream out = socket.getOutputStream();
while (true)
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = br.readLine();
out.write(line.getBytes());
}
}
catch (IOException e)
{
e.printStackTrace();
}
}}服务端测试类import java.net.ServerSocket;
import java.net.Socket;public class ServerTest
{
public static void main(String[] args) throws Exception
{
ServerSocket serverSocket = new ServerSocket(5000);
while (true)
{
Socket socket = serverSocket.accept();
new ServerTread(socket).start();
}
}
}
客户端测试类import java.net.Socket;public class ClientTest
{
public static void main(String[] args) throws Exception
{
Socket socket = new Socket("127.0.0.1", 5000);
new ClientTread(socket).start();
}
}
首先,很感谢你的代码 。
其次,你的代码用线程,的确不错
-------
但是,我依然想问几个问题:
1、我这个测试代码,不考虑线程,只要两个test之间通讯就可以了。
2、你的程序,并未解决我的问题,你的程序,只是单向发送数据,我也办得到!
3、我自己的提问是:
问题1:ClientTest.java第30行的注释里面写了,也就是: /***
* 第31行到34行
* 目的:一开启Client,就先尝试接收服务端发过来的信息
* 问题:运行程序,并未接到SocketTest服务端传来的提示信息,
* 我自己调试,发现貌似出现了阻塞,hasNextLine()阻塞了,
* 导致接收不到数据,但我不知道怎么改?
*/
问题2:
如果把30行开始的代码 while( serverSay.hasNextLine() ){
line = serverSay.nextLine() ;
System.out.println(line);
}
改成: //while( serverSay.hasNextLine() ){
line = serverSay.nextLine() ;
System.out.println(line);
//}
就能接到SocketTest数据,虽然只能接到一条数据,
但是,写完数据后,却无法发送回服务端SocketTest,非要Ctrl+C关闭程序时才能发送数据!
我推测是写的数据被放进了BUF缓存,可是我都out.flush()了?
--------------------
我这里提问,就是遇到了这两个问题,希望你能指点我下,谢谢!
http://kanpiaoxue.iteye.com/admin/blogs/1956800
你好,你这里有好多文章,看哪一篇呢 ? java net 编程(Socket,netty)
你好,你这里有好多文章,看哪一篇呢 ? java net 编程(Socket,netty) 可是我的代码错在哪里呢?
我的2个问题就在那 ...
可是真心不懂了!不是都说OuputStream负责发送,InputStream负责接受么?
那么我用Scanner(InputStream )后,scanner.hasNextLine()为什么就接收不了所有的?何况我还flush了。
为什么我的OutputStream无法发送,非要关闭程序才发送?我希望你能指点我一下 ... 可以么?
你好,你这里有好多文章,看哪一篇呢 ? java net 编程(Socket,netty) 可是我的代码错在哪里呢?
我的2个问题就在那 ...
可是真心不懂了!不是都说OuputStream负责发送,InputStream负责接受么?
那么我用Scanner(InputStream )后,scanner.hasNextLine()为什么就接收不了所有的?何况我还flush了。
为什么我的OutputStream无法发送,非要关闭程序才发送?我希望你能指点我一下 ... 可以么?你的具体的代码我没看。不过看了你的问题的描述,推测如下:
你的服务器端的 OuputStream write数据的时候,在里面添加\n了么?
因为你的clietn像是readLine()读取的数据,他需要\n来表示新的一行。
同时,你的client端发送数据给Server的时候,如果server也是用的readLine(),那么你client发送数据的时候,也需要添加\n来结尾,表示你的发送一个line已经结束。
为啥会阻塞?应该就是你没有添加\n,造成你的程序认为读取的流文件没有结束,而继续等待。
你好,你这里有好多文章,看哪一篇呢 ? java net 编程(Socket,netty) 可是我的代码错在哪里呢?
我的2个问题就在那 ...
可是真心不懂了!不是都说OuputStream负责发送,InputStream负责接受么?
那么我用Scanner(InputStream )后,scanner.hasNextLine()为什么就接收不了所有的?何况我还flush了。
为什么我的OutputStream无法发送,非要关闭程序才发送?我希望你能指点我一下 ... 可以么?你的具体的代码我没看。不过看了你的问题的描述,推测如下:
你的服务器端的 OuputStream write数据的时候,在里面添加\n了么?
因为你的clietn像是readLine()读取的数据,他需要\n来表示新的一行。
同时,你的client端发送数据给Server的时候,如果server也是用的readLine(),那么你client发送数据的时候,也需要添加\n来结尾,表示你的发送一个line已经结束。
为啥会阻塞?应该就是你没有添加\n,造成你的程序认为读取的流文件没有结束,而继续等待。首先,不得不承认,你是一个高手,的确,根据\n我解决了通讯问题,也就是说,我解决了【问题2】,
可是【问题1】没有解决。
如果我ClientTest.java中31-34行注释掉scanner.hasNextLine();如下:
//while( serverSay.hasNextLine() ){
line = serverSay.nextLine() ;
System.out.println(line);
//}
那么,加上\n程序可以通讯了。
-------------
但是:如果我没有注释掉ClientTest.java中31-34行的serverSay.hasNextLine(),如下:
while( serverSay.hasNextLine() ){
line = serverSay.nextLine() ;
System.out.println(line);
}
那么,程序在刚刚开启Client端时,获取了SocketTest(这是Server)的提示后,程序就阻塞了,
想请问下, 为什么scanner.hasNextLine()导致了阻塞呢?
我的执行效果如图:
while( serverSay.hasNextLine() ){
line = serverSay.nextLine() ;
System.out.println(line);
}
System.out.print("我说 : ") ;也就是说你的“我说 :”没有执行,依然阻塞在 serverSay.hasNextLine() 这里。问题的地方都找到了,原因应该也就出来了。看你的服务器输出,应该是你的服务器输出有问题,造成serverSay.hasNextLine()没结束,依然在等待。
解决这种client和server的通讯的关键在于:协议的一致性。比如client和server都采用\n表示内容的结束,都采用readline读取数据。这样协议是一致的,就不会出现你这种阻塞的问题。阻塞?为什么呢?就是通讯的协议不一致。
可是,我最新修改的代码里,也就是加了个"\n",别的都没干!
你看看我最新的SocketTest代码
try{
ServerSocket serverS = new ServerSocket(9000) ; Socket incoming = serverS.accept();
try{
OutputStream outStream = incoming.getOutputStream();
InputStream inStream = incoming.getInputStream() ;
outStream.write("Hello ! Enter BYE to exit .\n".getBytes()) ;
outStream.write("me[c]:\n".getBytes()); Scanner clientSay = new Scanner(inStream) ;
boolean done = false ;
while(!done && clientSay.hasNextLine() ){
System.out.print("Client : ") ;
String line = clientSay.nextLine() ;
System.out.println(line) ;
if( line.trim().equals("BYE") ) //如果客户端说了“BYE”,则准备结束链接
{
String end = "Server:goodbye ..." ;
byte[] bye = end.getBytes();
outStream.write(bye);
done = true ; //跳出 while 的条件
}
else
{
System.out.print("我说 : ");
String serverStr = "me[s] : "+consoleRead(null)+"\n\rme[c] :\n";
//byte[] serverSayBytes = (serverStr).getBytes();
outStream.write(serverStr.getBytes());
//outStream.flush();
System.out.println("......等待客户端回复...... :");
}
}// end while
}
finally{
incoming.close() ;
}
}
catch(Exception err){
err.printStackTrace() ;
}其中,:
OutputStream outStream = incoming.getOutputStream();
InputStream inStream = incoming.getInputStream() ;
outStream.write("Hello ! Enter BYE to exit .\n".getBytes()) ;
outStream.write("me[c]:\n".getBytes());
这里就是发送的地方,也就是Client已开启,就接到了:
Hello ! Enter BYE to exit .
me[c]:
[\n]
本来Client应该在[\n]位置输入的,可是依然不能输入,我寻找发现可能是:
while( serverSay.hasNextLine() ){
line = serverSay.nextLine() ;
System.out.println(line);
}
System.out.print("我说 : ") ;
这里的问题,可是我不明白为什么hasNextLine()此时还会阻塞,不出现“我说:”?
我这里Server都发送完了信息啊 ...
---------------
我找到了可能出现问题的地方(也可能找错了),但解决不了,
真心求教!
OutputStream outStream = incoming.getOutputStream();
InputStream inStream = incoming.getInputStream();
outStream.write("Hello ! Enter BYE to exit .\n".getBytes());
outStream.write("me[c]:\n".getBytes()); outStream.flush();//添加这行代码
查了下API,发现:flush()只是把BUF中的数据强行清空而已,自然效果不太大。
----------
继续求教 !
line = serverSay.nextLine() ;
System.out.println(line);
}
System.out.print("我说 : ") ;
额 ...
你这一问,恰好问到我的难处了!
我初学,感觉一close()程序就结束了,因为毕竟我程序里面while(){...}中要用到了close();请问:能贴下程序告诉我具体那里close()么?让我有一个实际的感官体会下!
谢谢
InputStream in = null ;
boolean done = false ;
while(!done)
{
out = s.getOutputStream();
in = s.getInputStream () ;
Scanner serverSay = new Scanner(in);
String line = "" ;
/***
* 目的:一开启Client,就先尝试接收服务端发过来的信息
* 问题:运行程序,并未接到SocketTest服务端传来的提示信息,
* 我自己调试,发现貌似出现了阻塞,hasNextLine()阻塞了,
* 导致接收不到数据,但我不知道怎么改?
*/
while( serverSay.hasNextLine() ){
line = serverSay.nextLine() ;
System.out.println(line);
}
我的Server端采用的是多线程的并发的生产者-消费者模式写的,提高并发的效率。你的程序的并发也不行,只能一次一个客户端聊天。我使用了一个线程池,你可以增加线程的数量来设置一次运行聊天的客户端的数量。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;/**
* <pre>
* @author kanpiaoxue
* Date 2013-11-27
* </pre>
*/
public class TalkSocketServer {
private static final Logger LOGGER = Logger
.getLogger(TalkSocketServer.class); class Producer implements Runnable {
private BlockingQueue<Socket> queue;
private ServerSocket server; public Producer(String name, BlockingQueue<Socket> queue, int port) {
super();
this.queue = queue;
try {
Thread.currentThread().setName(name);
server = new ServerSocket(port);
} catch (IOException e) {
LOGGER.error("Error:" + e.getMessage(), e);
}
} @Override
public void run() {
LOGGER.info(server + " start to work.");
while (true) {
try {
queue.put(server.accept());
} catch (Exception e) {
LOGGER.error("Error:" + e.getMessage(), e);
}
} }
} class Consumer implements Runnable { private BlockingQueue<Socket> queue; public Consumer(String name, BlockingQueue<Socket> queue) {
super();
this.queue = queue;
Thread.currentThread().setName(name);
} @Override
public void run() {
while (true) {
Socket socket = null;
try {
socket = queue.take();
consume(socket);
} catch (Exception e) {
LOGGER.error("Error:" + e.getMessage(), e);
} finally {
if (null != socket) {
try {
socket.close();
LOGGER.info(socket + " closed.");
} catch (IOException e) {
}
}
}
} } private void consume(Socket socket) throws Exception {
PrintWriter writer = new PrintWriter(socket.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
sendMsg(writer, "Welcome to talking system!");
for (String request = reader.readLine(); null != request; request = reader
.readLine()) {
if (request.trim().equalsIgnoreCase("bye")) {
sendMsg(writer, "Good bye " + socket + " !");
socket.close();
continue;
}
sendMsg(writer, socket + "You say [" + request + "] to me.");
} // close all resource
IOUtils.closeQuietly(writer);
IOUtils.closeQuietly(reader);
} private void sendMsg(PrintWriter writer, String msg) {
writer.println(msg);
writer.flush();
}
} /**
* @param args
*/
public static void main(String[] args) {
TalkSocketServer t = new TalkSocketServer();
ExecutorService exec = Executors.newCachedThreadPool();
BlockingQueue<Socket> queue = new LinkedBlockingQueue<Socket>();
int port = 7777;
exec.execute(t.new Producer("producer", queue, port));
for (int i = 0, j = Runtime.getRuntime().availableProcessors() * 2; i < j; i++) {
exec.execute(t.new Consumer("consumer-" + i, queue));
}
exec.shutdown();
}}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;/**
*
* @author kanpiaoxue
*
*/
public class TestSocketClient {
private static final Logger LOGGER = Logger
.getLogger(TestSocketClient.class); private Socket socket; /**
* @param host
* @param port
*/
public TestSocketClient(String host, int port) {
super();
try {
socket = new Socket(host, port);
LOGGER.info(socket + " start to work.");
} catch (Exception e) {
LOGGER.error("Error:" + e.getMessage(), e);
}
} public void talk() throws Exception {
BufferedReader localReader = new BufferedReader(new InputStreamReader(
System.in));
PrintWriter writer = new PrintWriter(socket.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
System.out.println(reader.readLine());
System.out.println("enter message :");
for (String request = localReader.readLine(); null != request; request = localReader
.readLine()) { sendMsg(writer, request);
System.out.println(reader.readLine());
} IOUtils.closeQuietly(localReader);
} private void sendMsg(PrintWriter writer, String msg) {
writer.println(msg);
writer.flush();
} /**
* @param args
*/
public static void main(String[] args) {
try {
new TestSocketClient("localhost", 7777).talk();
} catch (Exception e) {
LOGGER.error("Error:" + e.getMessage(), e);
} }}
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;/**
* <pre>
* @author kanpiaoxue
* Date 2013-11-27
* </pre>
*/
public class TalkSocketServer {
private static final Logger LOGGER = Logger
.getLogger(TalkSocketServer.class); class Producer implements Runnable {
private BlockingQueue<Socket> queue;
private ServerSocket server; public Producer(String name, BlockingQueue<Socket> queue, int port) {
super();
this.queue = queue;
try {
Thread.currentThread().setName(name);
server = new ServerSocket(port);
} catch (IOException e) {
LOGGER.error("Error:" + e.getMessage(), e);
}
} @Override
public void run() {
LOGGER.info(server + " start to work.");
while (true) {
try {
queue.put(server.accept());
} catch (Exception e) {
LOGGER.error("Error:" + e.getMessage(), e);
}
} }
} class Consumer implements Runnable { private BlockingQueue<Socket> queue; public Consumer(String name, BlockingQueue<Socket> queue) {
super();
this.queue = queue;
Thread.currentThread().setName(name);
} @Override
public void run() {
while (true) {
Socket socket = null;
try {
socket = queue.take();
consume(socket);
} catch (Exception e) {
LOGGER.error("Error:" + e.getMessage(), e);
} finally {
if (null != socket) {
try {
socket.close();
LOGGER.info(socket + " closed.");
} catch (IOException e) {
}
}
}
} } private void consume(Socket socket) throws Exception {
PrintWriter writer = new PrintWriter(socket.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
sendMsg(writer, "Welcome to talking system!");
for (String request = reader.readLine(); null != request; request = reader
.readLine()) {
if (request.trim().equalsIgnoreCase("bye")) {
sendMsg(writer, "Good bye " + socket + " !");
closeAll(writer, reader, socket);
break;
}
sendMsg(writer, socket + "You say [" + request + "] to me.");
} // close all resource
closeAll(writer, reader, socket);
} private void closeAll(Writer writer, Reader reader, Socket socket)
throws IOException {
IOUtils.closeQuietly(writer);
IOUtils.closeQuietly(reader);
socket.close();
} private void sendMsg(PrintWriter writer, String msg) {
writer.println(msg);
writer.flush();
}
} /**
* @param args
*/
public static void main(String[] args) {
TalkSocketServer t = new TalkSocketServer();
ExecutorService exec = Executors.newCachedThreadPool();
BlockingQueue<Socket> queue = new LinkedBlockingQueue<Socket>();
int port = 7777;
exec.execute(t.new Producer("producer", queue, port));
for (int i = 0, j = Runtime.getRuntime().availableProcessors() * 2; i < j; i++) {
exec.execute(t.new Consumer("consumer-" + i, queue));
}
exec.shutdown();
}}
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;/**
*
* @author kanpiaoxue
*
*/
public class TestSocketClient {
private static final Logger LOGGER = Logger
.getLogger(TestSocketClient.class); private Socket socket; /**
* @param host
* @param port
*/
public TestSocketClient(String host, int port) {
super();
try {
socket = new Socket(host, port);
LOGGER.info(socket + " start to work.");
} catch (Exception e) {
LOGGER.error("Error:" + e.getMessage(), e);
}
} public void talk() throws Exception {
BufferedReader localReader = new BufferedReader(new InputStreamReader(
System.in));
PrintWriter writer = new PrintWriter(socket.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
System.out.println(reader.readLine());
System.out.println("enter message :");
for (String request = localReader.readLine(); null != request; request = localReader
.readLine()) {
sendMsg(writer, request);
System.out.println(reader.readLine());
if (request.trim().equalsIgnoreCase("bye")) {
break;
}
} IOUtils.closeQuietly(localReader);
socket.close();
} private void sendMsg(PrintWriter writer, String msg) {
writer.println(msg);
writer.flush();
} /**
* @param args
*/
public static void main(String[] args) {
try {
new TestSocketClient("localhost", 7777).talk();
} catch (Exception e) {
LOGGER.error("Error:" + e.getMessage(), e);
} }}
BufferedReader localReader = new BufferedReader(new InputStreamReader(
System.in));
PrintWriter writer = new PrintWriter(socket.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
System.out.println(reader.readLine());
System.out.println("enter message :");
for (String request = localReader.readLine(); null != request; request = localReader
.readLine()) {
sendMsg(writer, request);
System.out.println(reader.readLine());
if (request.trim().equalsIgnoreCase("bye")) {
break;
}
} IOUtils.closeQuietly(localReader);
closeAll(writer, reader, socket); } private void closeAll(Writer writer, Reader reader, Socket socket)
throws IOException {
IOUtils.closeQuietly(writer);
IOUtils.closeQuietly(reader);
socket.close();
}
你的代码,导了 apache的common.io包。
其实,我刚入门,只是想2个程序通讯就好了。
--------------
但是碰到了如上的问题,所以,主要想解决如上的问题,不敢贪大求全!
--------------
你说我的server的outStream没有关,导致client的scanner.hasNextLine()一直在等待!
我初学,不太知道怎么关,因为我所了解的知识,close后就无法发送了!所以希望你指点下,就我的问题指导下。
求教!
1、我回去试试你的方法!
2、你的方法中,io流频繁开关,必然导致资源开销过大,耗时!所以,我觉得未必很好!
--------
不知有否更佳的方法 ?
求指教! 你客户端是分好几次读的,每次读完后
1、我回去试试你的方法!
2、你的方法中,io流频繁开关,必然导致资源开销过大,耗时!所以,我觉得未必很好!
--------
不知有否更佳的方法 ?
求指教! s.getInputStream() 接受一次数据,就关闭了,你下次接受数据的时候 又要调用一次s.getInputStream() 是这个意思
就是放进循环了,进入循环后getInputStream,到了while底部"}"后关闭?如果再次循环再次get??
while(){
in = socket.getInputStream() ;
/*do something*/
in.close();
}
你指的是这个意思把 ?
就是放进循环了,进入循环后getInputStream,到了while底部"}"后关闭?如果再次循环再次get??
while(){
in = socket.getInputStream() ;
/*do something*/
in.close();
}
你指的是这个意思把 ? 我上面说的不对 我觉得你那个跳出循环 serverSay.hasNextLine() 不对,读文件的话,读完会返回false,但是其他的,不会返回false,你应该查一下什么时候scanner.hasNext返回false,即system.in的结束标志。或者重新设置一个跳出循环的标志.
猜测你的目的是实现客户端、服务能自由交流,对此,做了如下一个分析(直接上图了):大致思路就是分两个socket,多线程实现。
源码如下:
服务端代码:import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class SocketTest {
public static void main(String[] args) {
time();
} public static void time() {
long start = System.currentTimeMillis();
// 专门负责向socket中写数据
Socket writeSocket = null;
// 专门负责从socket中读数据
Socket readSocket = null;
try {
ServerSocket serverS = new ServerSocket(9000);
System.out.println("---等待客户端连接---");
// 服务端写操作对应客户端端读操作的socket
writeSocket = serverS.accept();
// 服务端读操作对应客户端读操作的socket
readSocket = serverS.accept();
System.out.println("---开始接收客户端消息---"); // 读客户端信息
FutureTask<Integer> readFuture = new FutureTask<Integer>(new ReadFromSocket(readSocket));
new Thread(readFuture).start();
// 写服务端信息
FutureTask<Integer> writeFuture = new FutureTask<Integer>(new WriteToSocket(
writeSocket, "Server"));
new Thread(writeFuture).start(); // 通过future的get操作,使线程处于持有状态,从而线程没有返回就不会结束
if (0 == readFuture.get() && 0 == writeFuture.get()) {
System.out.println("正常结束");
} else {
System.out.println("异常结束");
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
// 关闭各种资源的正确流程
try {
if (null != writeSocket) {
writeSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
long end = System.currentTimeMillis();
System.out.println("总共连接时间:" + (end - start) + "(ms)");
}}
客户端代码:
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class ClientTest {
public static void main(String[] args) {
long start = System.currentTimeMillis();
start();
long end = System.currentTimeMillis();
System.out.println("总共连接时间:" + (end - start) + "(ms)");
} public static void start() {
// 专门负责从socket中读数据
Socket readSocket = new Socket();
// 专门负责向socket中写数据
Socket writeSocket = new Socket();
try {
// 客户端读操作对应服务端写操作的socket
readSocket.connect(new InetSocketAddress("127.0.0.1", 9000), 10000);// 连接不得超过10秒钟
// 客户端写操作对应服务端读操作的socket
writeSocket.connect(new InetSocketAddress("127.0.0.1", 9000), 10000);// 连接不得超过10秒钟
// 读服务端信息
FutureTask<Integer> readFuture = new FutureTask<Integer>(new ReadFromSocket(readSocket));
new Thread(readFuture).start();
// 写客户端信息
FutureTask<Integer> writeFuture = new FutureTask<Integer>(new WriteToSocket(
writeSocket, "Client"));
new Thread(writeFuture).start(); // 通过future的get操作,使线程处于持有状态,从而线程没有返回就不会结束
if (0 == readFuture.get() && 0 == writeFuture.get()) {
System.out.println("正常结束");
} else {
System.out.println("异常结束");
}
}// end try
catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} finally {
// 关闭各种资源的正确流程
try {
if (null != readSocket) {
readSocket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
写socket线程类:
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.Callable;public class WriteToSocket implements Callable<Integer> { // 可用的Socket链接
private Socket socket; // 角色
private String role; public WriteToSocket(Socket socket, String role) {
this.socket = socket;
this.role = role;
} @Override
public Integer call() throws Exception {
// 合法性判断
if (null == socket || !socket.isConnected()) {
System.out.println("非法的Socket链接!");
return -1;
}
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
Scanner sc = new Scanner(System.in);
String tmp = null;
for (; socket.isConnected() && !socket.isClosed();) {
tmp = sc.nextLine();
System.out.print("I say:" + tmp + System.getProperty("line.separator"));
bw.write(role + " say:" + tmp);
bw.newLine();
bw.flush();
if (tmp.endsWith("BYE")) {
break;
}
}
} catch (IOException e) {
System.out.println("Write---IO异常");
e.printStackTrace();
return -1;
} finally {
// 关闭各种资源的正确流程
if (null != socket) {
socket.close();
}
try {
if (null != bw) {
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
} return 0;
}
}
读socket线程类:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.concurrent.Callable;public class ReadFromSocket implements Callable<Integer> { // 可用的Socket链接
private Socket socket; public ReadFromSocket(Socket socket) {
this.socket = socket;
} @Override
public Integer call() throws Exception {
// 合法性判断
if (null == socket || !socket.isConnected()) {
System.out.println("非法的Socket链接!");
return -1;
}
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line = null;
while (!socket.isClosed() && socket.isConnected() && null != (line = br.readLine())) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("Read---IO异常");
e.printStackTrace();
return -1;
} finally {
// 关闭各种资源的正确流程
if (null != socket) {
socket.close();
}
try {
if (null != br) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return 0;
}}
版主可否帮忙看看这个问题http://bbs.csdn.net/topics/390655940