public class Server {
public static void main(String args[]) throws IOException {
//为了简单起见,所有的异常信息都往外抛
int port = 8889;
//定义一个ServerSocket监听在端口8899上
ServerSocket server = new ServerSocket(port);
System.out.println("ServerSocket kai shi");
while (true) {
//server尝试接收其他Socket的连接请求,server的accept方法是阻塞式的
System.out.println("accept kai shi");
Socket socket = server.accept();
//每接收到一个Socket就建立一个新的线程来处理它
new Thread(new Task(socket)).start();
}
}
/**
* 用来处理Socket请求的
*/
static class Task implements Runnable {
private Socket socket;
public Task(Socket socket) {
this.socket = socket;
}
public void run() {
try {
handleSocket();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 跟客户端Socket进行通信
* @throws Exception
*/
private void handleSocket() throws Exception {
System.out.println("handleSocket!!!");
//socket.setSoTimeout(2 * 1000);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "GBK"));
StringBuilder sb = new StringBuilder();
String temp;
int index;
while ((temp=br.readLine()) != null) {
// if ((index = temp.indexOf("eof")) != -1) {//
// sb.append(temp.substring(0, index));
// break;
// }
sb.append(temp);
}
System.out.println("客户端: " + sb);
//读完后写一句
Writer writer = new OutputStreamWriter(socket.getOutputStream(), "GBK");
writer.write("你好,客户端。");
writer.flush();
writer.close();
br.close();
socket.close();
}
}
}
再看客户端
public static void main(String[] args) throws Exception {
String host = "127.0.0.1"; //要连接的服务端IP地址
int port = 8889; //要连接的服务端对应的监听端口
//与服务端建立连接
Socket client = new Socket(host, port);
//建立连接后就可以往服务端写数据了
Writer writer = new OutputStreamWriter(client.getOutputStream(), "GBK");
writer.write("你好,服务端SSSSSSSSS");
writer.flush();
//写完以后进行读操作
BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream(), "GBK"));
//设置超时间为10秒
client.setSoTimeout(3*1000);
StringBuffer sb = new StringBuffer();
String temp;
int index;
try {
while ((temp=br.readLine()) != null) {
// if ((index = temp.indexOf("eof")) != -1) {
// sb.append(temp.substring(0, index));
// break;
// }
sb.append(temp);
}
System.out.println("服务端: " + sb.toString());
} catch (SocketTimeoutException e) {
e.printStackTrace();
System.out.println("数据读取超时。");
}
writer.close();
br.close();
client.close();
}
}
main程序启动 ServerSocket服务端, 之后main程序启动客户端调用服务端,
现在是:服务端接收到 客户端的数据, 但是客户端无法接受服务端的数据,异常是请求超时。
服务端的
ServerSocket kai shi
accept kai shi
accept kai shi
handleSocket!!!
客户端: 你好,服务端SSSSSSSSS
客户端的
java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at com.zbxsoft.carbidbank.utils.Alltest.main(Alltest.java:93)
数据读取超时。
11 个解决方案
#1
java.io是流阻塞的。
将服务端的handleSocket方法修改一下可以看到效果。
你会发现第一个readLine()执行之后就在等待,等到SoTimeout设置的时间到了,还没有读到数据所以第二个readLine()输入一个null.
回过头看一个原来的代码while ((temp=br.readLine()) != null) {,不难看出跳出while的时候正好就是timeout的时间。
一般在服务端将读和写分别用两个不同的线程处理互不影响
将服务端的handleSocket方法修改一下可以看到效果。
private void handleSocket() throws Exception {
System.out.println("handleSocket!!!");
// socket.setSoTimeout(2 * 1000);
BufferedReader br = new BufferedReader(new InputStreamReader(
socket.getInputStream(), "GBK"));
System.out.println("---->" + br.readLine());
System.out.println("---->" + br.readLine());
}
你会发现第一个readLine()执行之后就在等待,等到SoTimeout设置的时间到了,还没有读到数据所以第二个readLine()输入一个null.
回过头看一个原来的代码while ((temp=br.readLine()) != null) {,不难看出跳出while的时候正好就是timeout的时间。
一般在服务端将读和写分别用两个不同的线程处理互不影响
#2
那在实际开发中,都用什么办法呀, 是需要客户端和服务端 共同约定一个"end"字符吗? 客户端输出数据, 结尾加个"end"。
服务端接受数据时候,判断是否有end,跳出,再返回客户端吗,有没有例子呀,跪求提供
#3
那要看功能了,一般读和写分别线程。
说说需求。
说说需求。
#4
我们服务器 给银行提供几个 socket服务接口, 他请求过来,我们给他返回数据
银行 也给我们提供几个 socket服务接口, 我们去请求,他再返回数据
你提到的socket服务端 读取 和 写入 分别用两个线程,大哥给我源码实例吧,我刚毕业。
另外,启动项目的时候, 这时候要启动socket服务 , 也要用线程吧 。
我开始写了个 serlvet 去启动socket服务, 完后 , 项目启动后就不往下走了,原因是在 server.accept(); 堵塞了吧。
是不是启动项目的时候,也必须要用线程 启动socket服务。 通常是怎么做的呢
#5
客户端每次new 2个Socket c1,c2,服务端每次accept 2次得到2个socket s1,s2,
c1 读<------>s1 写
c2 写<------>s2 读
如果一问一答方式,可以在一个线程里,如果可能出现不按顺序的问答,就需要把这两组放到两个线程里。
c1 读<------>s1 写
c2 写<------>s2 读
如果一问一答方式,可以在一个线程里,如果可能出现不按顺序的问答,就需要把这两组放到两个线程里。
#6
如果一定要一组socket(c1,s1),就要严格遵循“一人一句”的方式:譬如c1先只一句,s1只读一句,s1再写一句,c1再读一句,完成一次会话。可以通过一些关键字判定是否继续这种问答方式。
#7
怎么会在servlet(java web服务器)中启动socket服务呢?bs和cs同在?
你是不是理解错了?
你是不是理解错了?
#8
这种方式错的,请忽略。。。
应该只能一方发消息,一方接收消息,不能交替:c1先只写一句,s1只读一句,c1再写一句,s1再读一句.....
#9
恩恩,多谢多谢,还有一些问题, 过后我必须结贴给你分!
我是菜啊,问个问题, 我的项目是javaweb, 在启动项目的时候, 这个时候同时也应该开启ServerSocket吧,
是不是大家一般都用ServletContextListener ,启动ServerSocket ?
启动ServerSocket 是不是大家都用多线程启动? 因为不多线程, 项目启动时候走到Socket.accept(); 就一直停止了。
我没有任何经验, 麻烦前辈多说几句
#10
如果一定要一组socket(c1,s1),就要严格遵循“一人一句”的方式:譬如c1先只一句,s1只读一句,s1再写一句,c1再读一句,完成一次会话。可以通过一些关键字判定是否继续这种问答方式。
这种方式错的,请忽略。。。
应该只能一方发消息,一方接收消息,不能交替:c1先只写一句,s1只读一句,c1再写一句,s1再读一句.....
恩恩,多谢多谢,还有一些问题, 过后我必须结贴给你分!
我是菜啊,问个问题, 我的项目是javaweb, 在启动项目的时候, 这个时候同时也应该开启ServerSocket吧,
是不是大家一般都用ServletContextListener ,启动ServerSocket ?
启动ServerSocket 是不是大家都用多线程启动? 因为不多线程, 项目启动时候走到Socket.accept(); 就一直停止了。
我没有任何经验, 麻烦前辈多说几句
分给1L吧,他说的对哦~
Socket编程实际使用的比较少(应该是无..),你的思路应该是对的:
1. ServerSocket 创建好放到一个地方存着
2. 每accept到一个(如果有交互,可能要2个)socket就放到线程里,形成一个会话
可能出问题的地方有2个:
1. ServerSocket要保证在应用启动时创建好
2. 会话未完成前,保证线程不会中断
#11
你在4L说的两个线程分别读写,我这有个demo你可以看看:
服务端启动:
客户端启动:
读线程实现:
写线程:
服务端启动:
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();
}
}
}
}
读线程实现:
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;
}
}
写线程:
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;
}
}
#1
java.io是流阻塞的。
将服务端的handleSocket方法修改一下可以看到效果。
你会发现第一个readLine()执行之后就在等待,等到SoTimeout设置的时间到了,还没有读到数据所以第二个readLine()输入一个null.
回过头看一个原来的代码while ((temp=br.readLine()) != null) {,不难看出跳出while的时候正好就是timeout的时间。
一般在服务端将读和写分别用两个不同的线程处理互不影响
将服务端的handleSocket方法修改一下可以看到效果。
private void handleSocket() throws Exception {
System.out.println("handleSocket!!!");
// socket.setSoTimeout(2 * 1000);
BufferedReader br = new BufferedReader(new InputStreamReader(
socket.getInputStream(), "GBK"));
System.out.println("---->" + br.readLine());
System.out.println("---->" + br.readLine());
}
你会发现第一个readLine()执行之后就在等待,等到SoTimeout设置的时间到了,还没有读到数据所以第二个readLine()输入一个null.
回过头看一个原来的代码while ((temp=br.readLine()) != null) {,不难看出跳出while的时候正好就是timeout的时间。
一般在服务端将读和写分别用两个不同的线程处理互不影响
#2
java.io是流阻塞的。
将服务端的handleSocket方法修改一下可以看到效果。private void handleSocket() throws Exception {
System.out.println("handleSocket!!!");
// socket.setSoTimeout(2 * 1000);
BufferedReader br = new BufferedReader(new InputStreamReader(
socket.getInputStream(), "GBK"));
System.out.println("---->" + br.readLine());
System.out.println("---->" + br.readLine());
}
你会发现第一个readLine()执行之后就在等待,等到SoTimeout设置的时间到了,还没有读到数据所以第二个readLine()输入一个null.
回过头看一个原来的代码while ((temp=br.readLine()) != null) {,不难看出跳出while的时候正好就是timeout的时间。
一般在服务端将读和写分别用两个不同的线程处理互不影响
那在实际开发中,都用什么办法呀, 是需要客户端和服务端 共同约定一个"end"字符吗? 客户端输出数据, 结尾加个"end"。
服务端接受数据时候,判断是否有end,跳出,再返回客户端吗,有没有例子呀,跪求提供
#3
那要看功能了,一般读和写分别线程。
说说需求。
说说需求。
#4
那要看功能了,一般读和写分别线程。
说说需求。
我们服务器 给银行提供几个 socket服务接口, 他请求过来,我们给他返回数据
银行 也给我们提供几个 socket服务接口, 我们去请求,他再返回数据
你提到的socket服务端 读取 和 写入 分别用两个线程,大哥给我源码实例吧,我刚毕业。
另外,启动项目的时候, 这时候要启动socket服务 , 也要用线程吧 。
我开始写了个 serlvet 去启动socket服务, 完后 , 项目启动后就不往下走了,原因是在 server.accept(); 堵塞了吧。
是不是启动项目的时候,也必须要用线程 启动socket服务。 通常是怎么做的呢
#5
客户端每次new 2个Socket c1,c2,服务端每次accept 2次得到2个socket s1,s2,
c1 读<------>s1 写
c2 写<------>s2 读
如果一问一答方式,可以在一个线程里,如果可能出现不按顺序的问答,就需要把这两组放到两个线程里。
c1 读<------>s1 写
c2 写<------>s2 读
如果一问一答方式,可以在一个线程里,如果可能出现不按顺序的问答,就需要把这两组放到两个线程里。
#6
如果一定要一组socket(c1,s1),就要严格遵循“一人一句”的方式:譬如c1先只一句,s1只读一句,s1再写一句,c1再读一句,完成一次会话。可以通过一些关键字判定是否继续这种问答方式。
#7
怎么会在servlet(java web服务器)中启动socket服务呢?bs和cs同在?
你是不是理解错了?
你是不是理解错了?
#8
如果一定要一组socket(c1,s1),就要严格遵循“一人一句”的方式:譬如c1先只一句,s1只读一句,s1再写一句,c1再读一句,完成一次会话。可以通过一些关键字判定是否继续这种问答方式。
这种方式错的,请忽略。。。
应该只能一方发消息,一方接收消息,不能交替:c1先只写一句,s1只读一句,c1再写一句,s1再读一句.....
#9
如果一定要一组socket(c1,s1),就要严格遵循“一人一句”的方式:譬如c1先只一句,s1只读一句,s1再写一句,c1再读一句,完成一次会话。可以通过一些关键字判定是否继续这种问答方式。
这种方式错的,请忽略。。。
应该只能一方发消息,一方接收消息,不能交替:c1先只写一句,s1只读一句,c1再写一句,s1再读一句.....
恩恩,多谢多谢,还有一些问题, 过后我必须结贴给你分!
我是菜啊,问个问题, 我的项目是javaweb, 在启动项目的时候, 这个时候同时也应该开启ServerSocket吧,
是不是大家一般都用ServletContextListener ,启动ServerSocket ?
启动ServerSocket 是不是大家都用多线程启动? 因为不多线程, 项目启动时候走到Socket.accept(); 就一直停止了。
我没有任何经验, 麻烦前辈多说几句
#10
如果一定要一组socket(c1,s1),就要严格遵循“一人一句”的方式:譬如c1先只一句,s1只读一句,s1再写一句,c1再读一句,完成一次会话。可以通过一些关键字判定是否继续这种问答方式。
这种方式错的,请忽略。。。
应该只能一方发消息,一方接收消息,不能交替:c1先只写一句,s1只读一句,c1再写一句,s1再读一句.....
恩恩,多谢多谢,还有一些问题, 过后我必须结贴给你分!
我是菜啊,问个问题, 我的项目是javaweb, 在启动项目的时候, 这个时候同时也应该开启ServerSocket吧,
是不是大家一般都用ServletContextListener ,启动ServerSocket ?
启动ServerSocket 是不是大家都用多线程启动? 因为不多线程, 项目启动时候走到Socket.accept(); 就一直停止了。
我没有任何经验, 麻烦前辈多说几句
分给1L吧,他说的对哦~
Socket编程实际使用的比较少(应该是无..),你的思路应该是对的:
1. ServerSocket 创建好放到一个地方存着
2. 每accept到一个(如果有交互,可能要2个)socket就放到线程里,形成一个会话
可能出问题的地方有2个:
1. ServerSocket要保证在应用启动时创建好
2. 会话未完成前,保证线程不会中断
#11
你在4L说的两个线程分别读写,我这有个demo你可以看看:
服务端启动:
客户端启动:
读线程实现:
写线程:
服务端启动:
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();
}
}
}
}
读线程实现:
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;
}
}
写线程:
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;
}
}