java socket TCP协议传输经常出现connect reset错误。传送的文件越大,报错的可能性越大。 这是咋回事?

时间:2022-02-19 17:55:45
服务器:
package tcp.server;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 使用TCP协议进行传输的服务器端
 * @author hcy
 *
 */
public class ServerMain
{
private static final int BUFFERSIZE = 1024;
//客户端发送的数据
private String input = null;
//返回给客户端的数据
private byte[] result = null;
//服务socket
private ServerSocket serverSocket = null;
//连接socket
private Socket connetcionSocket = null;
//输入数据流
private BufferedReader inFromClient = null;
//输出数据流
private DataOutputStream outTOClient = null;
//socket监听的端口号
private int port;

//记录处理的请求的个数
private static int cnt = 0;

/**
 * 默认监听的端口号为1234
 */
public ServerMain()
{
this(1234);
}

/**
 * 设置监听的端口号
 * @param port
 */
public ServerMain(int port)
{
this.port = port;

try
{
//创建serversocket
System.out.println("创建ServerSocket...");
serverSocket = new ServerSocket(this.port);

/*
 * 设置超时
 */
serverSocket.setSoTimeout(0);

} catch (IOException e)
{
// TODO Auto-generated catch block
System.out.println("创建ServerSocket出错...");
e.printStackTrace();
}
}

public void acceptConnection()
{
if(serverSocket == null)
{
System.out.println("服务器启动失败...");
return;
}
System.out.println("开始接受请求...");
while(true)
{
try
{
//接受请求cd 
connetcionSocket = serverSocket.accept();

/*
 * 
 */
connetcionSocket.setSoTimeout(0);

System.out.println("接受第"+(++cnt)+"个请求...");
System.out.println("主机地址:"+connetcionSocket.getInetAddress().getHostAddress());
System.out.println("端口:"+connetcionSocket.getPort());

//获得输入输出流
inFromClient = new BufferedReader(
new InputStreamReader(connetcionSocket.getInputStream())
);
outTOClient = new DataOutputStream(connetcionSocket.getOutputStream());

input = inFromClient.readLine();
System.out.println("请求数据:"+input);

File file = new File("1.jpg");
DataInputStream dis = new DataInputStream(new FileInputStream(file));
result = new byte[BUFFERSIZE];

System.out.println("输出数据...");
while(dis.read(result) != -1)
{
outTOClient.write(result);
outTOClient.flush();
// try
// {
// Thread.sleep(1);
// }
// catch (InterruptedException e)
// {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}

outTOClient.flush();
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
dis.close();
inFromClient.close();
outTOClient.close();
connetcionSocket.close();

System.out.println("请求处理结束。");
} catch (IOException e)
{
// TODO Auto-generated catch block
System.out.println("创建连接socket失败...");
e.printStackTrace();
}

if(cnt >= 1000)
{
break;
}
}

try
{
serverSocket.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return ;
}

/**
 * @param args
 */
public static void main(String[] args)
{
// TODO Auto-generated method stub
new ServerMain(1234).acceptConnection();
}

}

客户端:
package tcp.client;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * 使用TCP协议进行传输的客户端
 * 
 * @author hcy
 * 
 */
public class ClientMain
{
private static final int BUFFERSIZE = 1024;
// 主机名
private String hostname = null;
// 端口号
private int port;
// 输出到服务器的信息
private String data = null;
// 服务器返回的信息
private byte[] result = null;
// 向服务器的输出流
private DataOutputStream outToServer = null;
// 从服务器的输入流
private DataInputStream inFromServer = null;
// 连接socket
private Socket clientSocket = null;
// 接受到的文件的长度
private int length = 0;

/**
 * 默认的服务器主机名为localhost,端口为1234
 */
public ClientMain()
{
this("localhost", 1234);
}

/**
 * 设定服务器主机名和端口号
 * 
 * @param hostname
 * @param port
 */
public ClientMain(String hostname, int port)
{
this.hostname = hostname;
this.port = port;
}

public void connect()
{
try
{
System.out.println("创建socket连接.");
// 建立socket
clientSocket = new Socket(hostname, port);

// socket连接不限时
clientSocket.setSoTimeout(0);

System.out.println("主机名:" + hostname);
System.out.println("端口号:" + port);

// 获得输出流
outToServer = new DataOutputStream(clientSocket.getOutputStream());
// 获得输入流
inFromServer = new DataInputStream(clientSocket.getInputStream());

data = "Hello!This is client...\nGood night.\n";

System.out.println("发送数据.");
// 向服务器发送数据
outToServer.writeBytes(data);

result = new byte[BUFFERSIZE];

System.out.println("接受数据.");
File file = new File("2.jpg");
file.canWrite();
file.delete();

if (!file.createNewFile())
{
System.out.println("创建文件失败...");
return;
}
DataOutputStream tofile = new DataOutputStream(new FileOutputStream(file));

long startTime = System.currentTimeMillis();

int temp;
temp = inFromServer.read(result);
while (temp != -1)
{
length += temp;
if (length % (BUFFERSIZE * 10000) == 0)
{
System.out.print(".");
}

tofile.write(result);
tofile.flush();

temp = inFromServer.read(result);
}
long endTime = System.currentTimeMillis();

System.out.println();
tofile.flush();
tofile.close();

System.out.println("总用时: " + (endTime - startTime) / 1000 + " s.");
System.out.println("接受到文件大小: " + (length / 1024 / 1024) + " Mb.");
// System.out.println("平均传送速率: "+(length/1024/1024)/((long)(endTime-startTime)/1000)+" Mb/s");
System.out.println("关闭连接.");

inFromServer.close();
outToServer.close();
// 关闭socket
clientSocket.close();
}
catch (UnknownHostException e)
{
// TODO Auto-generated catch block
System.out.println("未知的主机名...");
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("IO错误!!");
try
{
inFromServer.close();
outToServer.close();
// 关闭socket
clientSocket.close();
}
catch (IOException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}

}

}

public String getHostname()
{
return hostname;
}

public void setHostname(String hostname)
{
this.hostname = hostname;
}

public int getPort()
{
return port;
}

public void setPort(int port)
{
this.port = port;
}

public String getData()
{
return data;
}

public void setData(String data)
{
this.data = data;
}

/**
 * @param args
 */
public static void main(String[] args)
{
// TODO Auto-generated method stub
new ClientMain("localhost", 1234).connect();
}

}

2 个解决方案

#1


inFromClient.close();
outTOClient.close();
这两行的关系,因为ClientMain端不知道对方流关闭了
可以不关闭 也可以用shutdownInput()和shutdownOutput()来半关闭

#2


ClientMain端不知道对方流关闭了 但ClientMain端还在发送请求

#1


inFromClient.close();
outTOClient.close();
这两行的关系,因为ClientMain端不知道对方流关闭了
可以不关闭 也可以用shutdownInput()和shutdownOutput()来半关闭

#2


ClientMain端不知道对方流关闭了 但ClientMain端还在发送请求