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();
 } 
}
}

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,103评论 18 139
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,517评论 6 13
  • 18.1 引言 TCP是一个面向连接的协议。无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接。本章将...
    张芳涛阅读 3,266评论 0 13
  • 个人认为,Goodboy1881先生的TCP /IP 协议详解学习博客系列博客是一部非常精彩的学习笔记,这虽然只是...
    贰零壹柒_fc10阅读 5,019评论 0 8
  • 站在三十岁的门槛上,回顾从前,畅想未来。 时间这厮说快很快,说慢很慢。 转眼间,我们都要三十岁了,昨天我们还是惹是...
    146195562bba阅读 404评论 0 1