Java多线程下的网络通信编程--图片传输
来源:互联网 发布:金庸武侠知乎 编辑:程序博客网 时间:2024/06/11 10:08
一、网络通信的两种方式
- TCP(传输控制协议)
TCP方式就类似于拨打电话,使用该种方式进行网络通讯时,需要建立专门的虚拟连接,然后进行可靠的数据传输,如果数据发送失败,则客户端会自动重发该数据。 - UDP(用户数据报协议)
UDP方式就类似于发送短信,使用这种方式进行网络通讯时,不需要建立专门的虚拟连接,传输也不是很可靠,如果发送失败则客户端无法获得
二、TCP与UDP的区别
两种传输方式都是实际的网络编程中进行使用,重要的数据一般使用TCP方式进行数据传输,而大量的非核心数据则都通过UDP方式进行传递,在一些程序中甚至结合使用这两种方式进行数据的传递。由于TCP需要建立专用的虚拟连接以及确认传输是否正确,所以使用TCP方式的速度稍微慢一些,而且传输时产生的数据量要比UDP稍微大一些。
TPC和UDP协议的区别
- 使用UDP时,每个数据报中都给出了完整的地址信息,因此无需要建立发送方和接收方的连接。
- 对于TCP协议,由于它是一个面向连接的协议,在socket之间进行数据传输之前必然要建立连接,所以在TCP中多了一个连接建立的时间
- 使用UDP传输数据时是有大小限制的,每个被传输的数据报必须限定在64KB之内。
- TCP没有这方面的限制,一旦连接建立起来,双方的socket就可以按统一的格式传输大量的数据。
- UDP是一个不可靠的协议,发送方所发送的数据报并不一定以相同的次序到达接收方。
- TCP是一个可靠的协议,它确保接收方完全正确地获取发送方所发送的全部数据
- TCP在网络通信上有极强的生命力,例如远程连接(Telnet)和文件传输(FTP)都需要不定长度的数据被可靠地传输。相比之下UDP操作简单,而且仅需要较少的监护,因此通常用于局域网高可靠性的分散系统中client/server应用程序
三、实例
下面的实例是基于TCP协议完成的
首先,我们要有一个服务端Server
package com.webpic.test;import java.net.InetAddress;import java.net.InetSocketAddress;import java.net.ServerSocket;/** * 服务端 * @author zkc * */public class Server { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub try { //创建套接字对象 ServerSocket ss = new ServerSocket(); //将套接字绑定到指定的ip地址(由于我是一台机器,所以我指定的是自己的ip地址),并指定端口号(9090) ss.bind(new InetSocketAddress(InetAddress.getByName("192.168.8.54"),9090)); //启动连接线程 new Thread(new Connect(ss)).start(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
接着是接收连接对象类
package com.webpic.test;import java.net.ServerSocket;import java.net.Socket;/** * 接收连接对象类 * @author zkc * */public class Connect implements Runnable { //套接字对象 private ServerSocket ss; public Connect(ServerSocket ss){ this.ss = ss; } @Override public void run() { // TODO Auto-generated method stub try { //等待用户连接(这里写true意思是让服务端一直等待,直到有人连接) while(true){ System.out.println("等待用户连接"); //侦听并接受到此套接字的连接 Socket conn = ss.accept(); //在控制台输出谁连接成功了 System.out.println(conn.getInetAddress().getHostAddress()+"连接成功"); //启动传输图片线程 new Thread(new SendPic(conn)).start(); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } }}
然后是传输图片类
package com.webpic.test;import java.io.FileInputStream;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import java.util.Scanner;/** * 传输图片类 * @author zkc * */public class SendPic implements Runnable { //客户端套接字 private Socket conn; public SendPic(Socket conn){ this.conn = conn; } @Override public void run() { // TODO Auto-generated method stub try { System.out.println("请输入要传输的图片名称"); Scanner sc = new Scanner(System.in); String name = sc.nextLine(); //创建文件输入流对象fis,图片要传输出去,首先要从文件中读取,所以是创建输入流 FileInputStream fis = new FileInputStream("C:\\Users\\zkc\\Desktop\\zkc\\"+name+".jpg"); //获取输出流对象os OutputStream os = conn.getOutputStream(); //将图片存入byte数组 byte[] b = new byte[1024]; int nRead = 0; while((nRead = fis.read(b))!=-1){ //写入输出流 os.write(b,0,nRead); } //禁用此套接字的输出流 conn.shutdownOutput(); //获取服务端输入流对象is与客户端对应的输出流对象os中的信息 InputStream is = conn.getInputStream(); byte[] recv = new byte[1024]; System.out.println(new String(recv, 0, is.read(recv))); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } }}
服务端的编写就OK了,接下来是客户端,相比于服务端,客户端就比较简单了。
首先是客户端
package com.webpic.test;import java.net.Socket;import java.util.Random;/** * 客户端 * @author zkc * */public class Client { /** * 生成随机图片名称方法 * @param length * @return String */ public static String getRandomString(int length) { char[] chr = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'}; Random random = new Random(); StringBuffer buffer = new StringBuffer(); for (int i = 0; i < length; i++) { buffer.append(chr[random.nextInt(36)]); } return buffer.toString(); } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub try { //客户端套接字对象并与服务端ip和端口绑定 Socket s = new Socket("192.168.8.54",9090); //启动线程 new Thread(new ReceivePic(s)).start(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
其次就是接收图片类
package com.webpic.test;import java.io.File;import java.io.FileOutputStream;import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;import com.web.bean.clientpic;/** * 接收图片类 * @author zkc * */public class ReceivePic implements Runnable{ private Socket conn; public ReceivePic(Socket conn){ this.conn = conn; } @Override public void run() { // TODO Auto-generated method stub try { InputStream is = conn.getInputStream(); OutputStream os = conn.getOutputStream(); File file = new File("G:\\image"); //路径是否存在,不存在则创建 if(!file.exists()){ file.mkdirs(); } //创建文件输出流对象fos,也就是传输过来的图片,并生产随机的名字 FileOutputStream fos = new FileOutputStream(file.getAbsolutePath()+"\\"+clientpic.getRandomString(40)+".jpg"); byte[] b = new byte[1024]; int nRead = 0; while((nRead = is.read(b))!=-1){ //写入图片 fos.write(b,0,nRead); } //关闭流 fos.close(); //给服务端相应输入流发送信息 os.write("传输成功".getBytes()); //禁用套接字的输出流 conn.shutdownOutput(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } }}
以上,客户端和服务端都编写完毕,可以运行了。
以下是运行时的截图
我们传输一张图片
首先启动服务端
再启动客户端,我们发现,自己和自己连接成功了
输入相应的图片名字,再打开相应的文件夹查看是否成功
到这里,我们就完成了该实例。
由于我是在本机上进行测试,所以不能体现出多线程的特点,也就是可以连接多个客户端同时进行图片的传输,不过我们确实是完成了这一项功能,有兴趣的可以自己尝试一下。
阅读全文
0 0
- Java多线程下的网络通信编程--图片传输
- Java网络编程+多线程通信
- java tcp 网络通信--使用多线程传输文件
- 多线程下的Socket网络通信
- java网络编程学习之——构建基于多线程的网络通信模型1
- Linux 下 C 网络编程之 多线程通信 实例
- Linux 下 C 网络编程之 多线程通信 实例
- Java 网络编程三 TCP传输协议(例:传输文本、图片)
- java 网络编程 基于TCP ,UDP的网络传输
- java socket通信-传输文件图片_传输图片
- java socket通信-传输文件图片--传输图片
- java socket通信-传输文件图片--传输图片
- java socket通信-传输文件图片--传输图片
- 多线程的网络通信
- Java基础—网络编程【OSI/RM TCP/IP】【网络通信三要素】【UDP传输 & TCP传输】【DNS域名解析】
- Java基础—网络编程【OSI/RM TCP/IP】【网络通信三要素】【UDP传输 & TCP传输】【DNS域名解析】
- Java基础—网络编程【OSI/RM TCP/IP】【网络通信三要素】【UDP传输 & TCP传输】【DNS域名解析】
- Java-网络编程(TCP传输)
- Arduino寻迹与识别红绿灯
- java面向对象
- 2017 ccpc 秦皇岛C Crusaders Quest
- java基础复习(类和对象)
- selenium得到一个动态页面
- Java多线程下的网络通信编程--图片传输
- 2017 ccpc 秦皇岛E String of CCPC
- Scala学习
- 2017 ccpc秦皇岛L One-Dimensional Maze
- [Leetcode] Union Find
- 【Android】源码分析
- C#如何以管理员身份运行程序
- 麻省理工学院-2017年-深度学习与自动驾驶视频课程分享
- 你的眼光应该放长远些——明辨