【Java TCP阻塞问题...在线等...】有没有好心人帮我看看为什么这段代码会阻塞啊?
最近看了一本《Java TCP/IP Socket》书中讲解了关于Socket的一些内容,其中看到关于阻塞的内容后,有点想不明白,大家能不能帮我看看代码,为什么会出现阻塞啊?
例子中有两种情况,情况1:不会出现阻塞;情况2:会出现阻塞;
代码如下:
//客户端
public class CompressClient
{
public static final int BUFSIZE = 256;
public static void main(String[] args) throws IOException
{
InetAddress inetAddr = InetAddress.getLocalHost();
int port = 8888;
String fileName = "D:\\杂乱\\桌面.jpg";
FileOutputStream fileOut = new FileOutputStream(fileName + ".gz");
final FileInputStream fileIn = new FileInputStream(new File(fileName));
final Socket sock = new Socket(inetAddr, port);
// 情况一:不会出现阻塞
// Thread thread = new Thread()
// {
// @Override
// public void run()
// {
// try
// {
// sendBytes(sock, fileIn);
// }
// catch (IOException e)
// {
// e.printStackTrace();
// }
// }
// };
// thread.start();
// 情况二:会出现阻塞
sendBytes(sock, fileIn);
// 接收压缩服务器信息
InputStream sockIn = sock.getInputStream();
int bytesRead;
byte[] buffer = new byte[BUFSIZE];
while ((bytesRead = sockIn.read(buffer)) != -1)
{
fileOut.write(buffer, 0, bytesRead);
System.out.print("R");
}
System.out.println();
fileIn.close();
fileOut.close();
sock.close();
}
private static void sendBytes(Socket socket, InputStream fileIn)
throws IOException
{
OutputStream sockOut = socket.getOutputStream();
int bytesRead = 0;
byte[] buffer = new byte[BUFSIZE];
while ((bytesRead = fileIn.read(buffer)) != -1)
{
sockOut.write(buffer, 0, bytesRead);
System.out.print("W");
}
System.out.println("\nClient send data complete!");
socket.shutdownOutput();
System.out.println("Client is deadlock? No");
}
}
//服务端
public class TCPEchoServerExecutor
{
public static void main(String[] args) throws IOException
{
int echoServProt = 8888;
ServerSocket servSock = new ServerSocket(echoServProt);
Logger logger = Logger.getLogger("practical");
Executor service = Executors.newCachedThreadPool();
while (true)
{
Socket clntSock = servSock.accept();
service.execute(new CompressProtocol(clntSock, logger));
}
}
}
//线程任务类
public class CompressProtocol implements Runnable
{
public static final int BUFSIZE = 1024;
private Socket clntSock;
private Logger logger;
public CompressProtocol(Socket clntSock, Logger logger)
{
this.clntSock = clntSock;
this.logger = logger;
}
public static void handleCompressClient(Socket clntSock, Logger logger)
{
try
{
InputStream in = clntSock.getInputStream();
GZIPOutputStream out = new GZIPOutputStream(
clntSock.getOutputStream());
byte[] buffer = new byte[BUFSIZE];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1)
{
out.write(buffer, 0, bytesRead);
}
out.finish();
logger.info("Server:" + clntSock.getRemoteSocketAddress()
+ " finished");
}
catch (IOException e)
{
logger.log(Level.WARNING, "Exception in echo protocol", e);
}
try
{
clntSock.close();
}
catch (IOException e)
{
logger.info("Exception = " + e.getMessage());
}
}
@Override
public void run()
{
handleCompressClient(clntSock, logger);
}
}
System.out.print("W");
}
System.out.println("\nClient send data complete!");
socket.shutdownOutput();
System.out.println("Client is deadlock? No");
}
这段代码有问题,
[解决办法]
//不管是客户机,还是服务器程序,你这段代码只能是学习用, 要用到项目中去, 不能这么简单的写.
while ((bytesRead = in.read(buffer)) != -1)
{
out.write(buffer, 0, bytesRead);
}
try{
int pava=0;
int cava=0;
int sumb=0;
int i=0;
int c=0;
ByteArrayOutputStream buffeOut =new ByteArrayOutputStream();
byte readbuf[] = new byte[10240];
while (socket.isConnected() && !socket.isClosed()) {
i++;
pava =in.available();
if(pava>0){
while ((c = in.read(readbuf)) != -1) {
buffeOut.write(readbuf, 0, c);
sumb =sumb + c;
cava =in.available();
if(cava<=0){
Thread.sleep(100);
cava =in.available();
if(cava<=0) break;
}
}
String strin = new String(buffeOut.toByteArray(),"utf-8");
System.out.println("读取流数据内容: "+strin+","+sumb);
buffeOut.reset();
//读完后回复信息.
out.write((i+",我是服务器,已收到数据!").getBytes("utf-8"));
out.flush();
if(c == -1) break;//对方关闭了输入流.
}else{
sumb=0;
out.write((i+",我是服务器,请发送数据!").getBytes("utf-8"));
out.flush();
Thread.sleep(1000);
}
}
} catch (SocketException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
System.out.println("Request,NO["+requestCount+"],读取流数据完成.");
}