Java中TCP传输、上传文件、上传图片、多并发上传

TCP传输

TCP传输是怎样建立的呢?

  • Socket和ServerSocket
  • 建立客户端和服务器端
  • 建立连接后,通过Socket中的IO流进行数据的传输
  • 关闭socket

TCP传输客户端与服务器端同样是两个独立的应用程序。
我们就来写一个TCP输出数据的程序。

TCP传输-客户端

/* 
* TCP协议发送数据: 
* A:创建发送端的Socket对象 
* 这一步如果成功,就说明连接已经建立成功了。
* B:获取输出流,写数据 
* C:释放资源 
*/
public class ClientDemo { 
public static void main(String[] args) throws IOException {
 // 创建发送端的Socket对象 
Socket s = new Socket("192.168.2.102", 8888); 
// 获取输出流,写数据 
OutputStream os = s.getOutputStream(); 
os.write("TCP来了".getBytes()); 
// 释放资源
 s.close(); 
}
}

TCP传输-服务器

/* 
* TCP协议接收数据:
* A:创建接收端的Socket对象 
* B:监听客户端连接。返回一个对应的Socket对象 
* C:获取输入流,读取数据显示在控制台 
* D:释放资源 */
public class ServerDemo { 
public static void main(String[] args) throws IOException { 
// 创建接收端的Socket对象 
ServerSocket ss = new ServerSocket(8888); 
// 监听客户端连接。返回一个对应的Socket对象 
Socket s = ss.accept(); // 侦听并接受到此套接字的连接。此方法在连接传入之前一直阻塞。 
// 获取输入流,读取数据显示在控制台 
InputStream is = s.getInputStream();
 byte[] bys = new byte[1024]; 
int len = is.read(bys); 
// 阻塞式方法 
String str = new String(bys, 0, len); 
String ip = s.getInetAddress().getHostAddress(); 
System.out.println(ip + "---" + str);
 // 释放资源
 s.close(); 
// ss.close();  //服务器一般不应该关闭 
}
}

这样我们九建立了TCP协议传输数据的客户端和服务器,运行程序,服务器会收到客户端发来的数据,但是这样的代码,当服务器端收到客户端的数据时,客户端并不知道,所以,我们就要给客户端一个反馈了。

/* * 服务器端 */
public class ServerDemo { 
public static void main(String[] args) throws IOException {
 // 创建服务器Socket对象 
ServerSocket ss = new ServerSocket(11111); 
// 监听客户端的连接 
Socket s = ss.accept(); // 阻塞 
// 获取输入流
 InputStream is = s.getInputStream(); 
byte[] bys = new byte[1024]; 
int len = is.read(bys); // 阻塞 
String server = new String(bys, 0, len); 
System.out.println("server:" + server); 
// 获取输出流
 OutputStream os = s.getOutputStream(); o
s.write("数据已经收到".getBytes()); 
// 释放资源 
s.close(); 
// ss.close(); 
}
}
/* * 客户端 */
public class ClientDemo { 
public static void main(String[] args) throws IOException { 
// 创建客户端Socket对象 
Socket s = new Socket("192.168.2.102",11111); 
// 获取输出流 
OutputStream os = s.getOutputStream(); 
os.write("双十一快乐!".getBytes());
 // 获取输入流
 InputStream is = s.getInputStream();
 byte[] bys = new byte[1024]; 
int len = is.read(bys);// 阻塞 
String client = new String(bys, 0, len); 
System.out.println("client:" + client); 
// 释放资源 
s.close(); 
}
}

上传文件

我们来完成通过TCP协议从客户端上传一个文件到服务器,并给出客户端反馈文件上传成功

/* * 上传文件客户端 */
public class UploadClient { 
public static void main(String[] args) throws IOException { 
// 创建客户端Socket对象 
Socket s = new Socket("192.168.2.102", 12345); 
// 封装文本文件 
BufferedReader br = new BufferedReader(new FileReader("a.txt")); 
// 封装通道内流 
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter( s.getOutputStream())); 
String line = null; 
while ((line = br.readLine()) != null) { 
// 阻塞 
bw.write(line);
 bw.newLine();
 bw.flush(); 
} 
//Socket提供了一个终止,它会通知服务器你别等了,我没有数据过来了
 s.shutdownOutput(); 
// 接收反馈 
BufferedReader brClient = new BufferedReader(new InputStreamReader( s.getInputStream())); 
String client = brClient.readLine(); // 阻塞 
System.out.println(client); 
// 释放资源 
br.close();
 s.close();
 }
}
/* * 上传文件接收端(服务器) */
public class UploadServer { 
public static void main(String[] args) throws IOException { 
// 创建服务器端的Socket对象 
ServerSocket ss = new ServerSocket(12345);
 // 监听客户端连接 
Socket s = ss.accept();// 阻塞 
// 封装通道内的流 
BufferedReader br = new BufferedReader(new InputStreamReader( s.getInputStream())); 
// 封装文本文件 
BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt")); String line = null;
 while ((line = br.readLine()) != null) {
 // 阻塞 
bw.write(line); 
bw.newLine();
 bw.flush(); 
} 
// 给出反馈 
BufferedWriter bwServer = new BufferedWriter(new OutputStreamWriter( s.getOutputStream())); 
bwServer.write("文件上传成功"); 
bwServer.newLine();
 bwServer.flush(); 
// 释放资源
 bw.close();
 s.close(); 
}
}

这是上传文件并给出反馈的例子,我们再来看上传图片并给出反馈的例子怎么写

上传图片

上传图片我们就要考虑不能用字符流了,要用字节流。

/* * 上传图片客户端 */
public class UploadClient { 
public static void main(String[] args) throws IOException { 
// 创建客户端Socket对象 
Socket s = new Socket("192.168.2.102", 96320); 
// 封装图片文件 
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.jpg")); 
// 封装通道内的流
 BufferedOutputStream bos = new BufferedOutputStream(s.getOutputStream());
 byte[] bys = new byte[1024]; 
int len = 0;
 while ((len = bis.read(bys)) != -1) { 
bos.write(bys, 0, len); 
bos.flush(); 
} 
s.shutdownOutput(); // 读取反馈
 InputStream is = s.getInputStream(); 
byte[] bys2 = new byte[1024]; 
int len2 = is.read(bys2); 
String client = new String(bys2, 0, len2); 
System.out.println(client); 
// 释放资源 
bis.close(); s.close(); 
}
}
/* * 上传图片接收端-服务器 */
public class UploadServer { 
public static void main(String[] args) throws IOException { 
// 创建服务器Socket对象 
ServerSocket ss = new ServerSocket(96320); 
// 监听客户端连接 
Socket s = ss.accept(); 
// 封装通道内流 
BufferedInputStream bis = new BufferedInputStream(s.getInputStream());
 // 封装图片文件 
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.jpg")); 
byte[] bys = new byte[1024];
 int len = 0; 
while ((len = bis.read(bys)) != -1) {
 bos.write(bys, 0, len); 
bos.flush(); 
} 
// 给一个反馈 
OutputStream os = s.getOutputStream(); 
os.write("图片上传成功".getBytes());
 bos.close();
 s.close(); 
}
}

运行程序,我们将客户端a.jpg的图片上传到服务器后,服务器收到后会给我们返回图片上传成功

多并发上传

在我们平时遇到的情况肯定不是一个客户端对应一个服务器,肯定是多个客户端对应一个服务器,那么就存在了多并发上传,再大型项目中也要考虑服务器的负荷问题,那么我们就来用代码实现一下当多个用户上传文件到服务器时,我们应该怎样做?

如果我们还按照上面上传文件的思路,去进行多并发上传,当一个客户端A建立连接之后,被服务端获取到,服务端就在执行代码了,这个时候如果客户端B建立连接只有等待客户端A操作完成后它才能开始执行,所以为了让多个客户端同时连接到服务器上传代码,我们就要运用多线程技术,把每个客户端和服务器之间的连接封装到一个线程中去,这样就可以同时处理多个客户端请求

/* * 服务器端 */
public class UploadServer { 
public static void main(String[] args) throws IOException { 
// 创建服务器Socket对象 
ServerSocket ss = new ServerSocket(11111);
 while (true) {
 Socket s = ss.accept(); 
new Thread(new UserThread(s)).start(); 
} 
}
}

/* * 并发的线程 */
public class UserThread implements Runnable { 
private Socket s; 
public UserThread(Socket s) { 
this.s = s;
 } 
@Override 
public void run() { 
try { 
// 封装通道内的流 
BufferedReader br = new BufferedReader(new InputStreamReader( s.getInputStream())); 
// 为了防止名称冲突,每次命名为随机的 
String newName = System.currentTimeMillis() + ".java"; BufferedWriter bw = new BufferedWriter(new FileWriter(newName)); String line = null; 
while ((line = br.readLine()) != null) { 
// 阻塞 
bw.write(line); 
bw.newLine();
 bw.flush(); 
} 
// 给出反馈 
BufferedWriter bwServer = new BufferedWriter( new OutputStreamWriter(s.getOutputStream())); 
bwServer.write("文件上传成功"); 
bwServer.newLine(); 
bwServer.flush(); 
// 释放资源 
bw.close();
 s.close(); 
} catch (IOException e) { 
e.printStackTrace();
 } 
}
}

这样就完成了多用户上传文件到客户端了。

你可能感兴趣的:(Java中TCP传输、上传文件、上传图片、多并发上传)