原文:http://blog.csdn.net/shimiso/article/details/8529633

什么是Socket?

所谓Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信连的句柄,应用程序通常通过“套接字”向网络发送请求或者应答网络请求,它就是网络通信过程中端点的抽象表示。它主要包括以下两个协议:

TCP (Transmission Control Protocol 传输控制协议):传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。
      UDP (User Datagram Protocl 用户数据报协议):用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快。

详细解说如下:

TCP传输和UDP不一样,TCP传输是流式的,必须先建立连接,然后数据流沿已连接的线路(虚电路)传输。因此TCP的数据流不会像UDP数据报一样,每个数据报都要包含目标地址和端口,因为每个数据报要单独路由。TCP传输则只需要在建立连接时指定目标地址和端口就可以了。

  形象的讲,TCP就像打电话,UDP就像发电报。宏观上来看UDP是不分客户端和服务端的。通信双方是平等的。微观上来讲只相对一个报文,发送端是客户端,监听端是服务端。发送端把数据报发给路由器就像把电报发给了邮局,后面的事情就是发送者无法控制,也无从知晓的了。所以说是不可靠的,可能会出现报文丢失而无从知晓。就像每张电报都要有收件人一样,每个数据报都要有目的地址和端口。

  而TCP每次连接都是分客户端和服务端的。连接的发起者(相当与拨号打电话的人)是客户端,监听者(相当于在电话边等着接电话的人)是服务端。发起者指定要连接的服务器地址和端口(相当于拨号),监听者通过和发起者三次握手建立连接(相当于听到电话响去接电话)。建立连接后双方可以互相发送和接受数据(打电话)。

Java如何操作Socket?

值得一提的是,Java分别为TCP和UDP提供了相应的类,TCP是java.net中提供了两个类Socket和ServerSocket,分别用来表示双向连接的客户端和服务端。这是两个封装得非常好的类,使用起来很方便!UDP是java.net.DatagramSocket.

127.0.0.1是回路地址,用于测试,相当于localhost本机地址,没有网卡,不设DNS都可以访问,端口地址在0~65535之间,其中0~1023之间的端口是用于一些知名的网络服务和应用,用户的普通网络应用程序应该使用1024以上的端口.

Socket通信模型如下:

如果大家对Java Socket编程还有模糊的地方抓紧温习(http://blog.csdn.net/shimiso/article/details/8529941),本文不在此赘述,下面我们以最常用的TCP协议举例:

服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。
客户端,使用Java socket通信对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。

TCP网络连接模型:

Android客户端程序代分析:

  1. UploadActivity.java
  2. package com.android.upload;
  3. import java.io.File;
  4. import java.io.OutputStream;
  5. import java.io.PushbackInputStream;
  6. import java.io.RandomAccessFile;
  7. import java.net.Socket;
  8. import android.app.Activity;
  9. import android.os.Bundle;
  10. import android.os.Environment;
  11. import android.os.Handler;
  12. import android.os.Message;
  13. import android.view.View;
  14. import android.view.View.OnClickListener;
  15. import android.widget.Button;
  16. import android.widget.EditText;
  17. import android.widget.ProgressBar;
  18. import android.widget.TextView;
  19. import android.widget.Toast;
  20. import com.android.service.UploadLogService;
  21. import com.android.socket.utils.StreamTool;
  22. public class UploadActivity extends Activity {
  23. private EditText filenameText;
  24. private TextView resulView;
  25. private ProgressBar uploadbar;
  26. private UploadLogService logService;
  27. private boolean start=true;
  28. private Handler handler = new Handler(){
  29. @Override
  30. public void handleMessage(Message msg) {
  31. int length = msg.getData().getInt("size");
  32. uploadbar.setProgress(length);
  33. float num = (float)uploadbar.getProgress()/(float)uploadbar.getMax();
  34. int result = (int)(num * 100);
  35. resulView.setText(result+ "%");
  36. if(uploadbar.getProgress()==uploadbar.getMax()){
  37. Toast.makeText(UploadActivity.this, R.string.success, 1).show();
  38. }
  39. }
  40. };
  41. @Override
  42. public void onCreate(Bundle savedInstanceState) {
  43. super.onCreate(savedInstanceState);
  44. setContentView(R.layout.main);
  45. logService = new UploadLogService(this);
  46. filenameText = (EditText)this.findViewById(R.id.filename);
  47. uploadbar = (ProgressBar) this.findViewById(R.id.uploadbar);
  48. resulView = (TextView)this.findViewById(R.id.result);
  49. Button button =(Button)this.findViewById(R.id.button);
  50. Button button1 =(Button)this.findViewById(R.id.stop);
  51. button1 .setOnClickListener(new OnClickListener() {
  52. @Override
  53. public void onClick(View v) {
  54. start=false;
  55. }
  56. });
  57. button.setOnClickListener(new View.OnClickListener() {
  58. @Override
  59. public void onClick(View v) {
  60. start=true;
  61. String filename = filenameText.getText().toString();
  62. if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
  63. File uploadFile = new File(Environment.getExternalStorageDirectory(), filename);
  64. if(uploadFile.exists()){
  65. uploadFile(uploadFile);
  66. }else{
  67. Toast.makeText(UploadActivity.this, R.string.filenotexsit, 1).show();
  68. }
  69. }else{
  70. Toast.makeText(UploadActivity.this, R.string.sdcarderror, 1).show();
  71. }
  72. }
  73. });
  74. }
  75. /**
  76. * 上传文件
  77. * @param uploadFile
  78. */
  79. private void uploadFile(final File uploadFile) {
  80. new Thread(new Runnable() {
  81. @Override
  82. public void run() {
  83. try {
  84. uploadbar.setMax((int)uploadFile.length());
  85. String souceid = logService.getBindId(uploadFile);
  86. String head = "Content-Length="+ uploadFile.length() + ";filename="+ uploadFile.getName() + ";sourceid="+
  87. (souceid==null? "" : souceid)+"\r\n";
  88. Socket socket = new Socket("192.168.1.78",7878);
  89. OutputStream outStream = socket.getOutputStream();
  90. outStream.write(head.getBytes());
  91. PushbackInputStream inStream = new PushbackInputStream(socket.getInputStream());
  92. String response = StreamTool.readLine(inStream);
  93. String[] items = response.split(";");
  94. String responseid = items[0].substring(items[0].indexOf("=")+1);
  95. String position = items[1].substring(items[1].indexOf("=")+1);
  96. if(souceid==null){//代表原来没有上传过此文件,往数据库添加一条绑定记录
  97. logService.save(responseid, uploadFile);
  98. }
  99. RandomAccessFile fileOutStream = new RandomAccessFile(uploadFile, "r");
  100. fileOutStream.seek(Integer.valueOf(position));
  101. byte[] buffer = new byte[1024];
  102. int len = -1;
  103. int length = Integer.valueOf(position);
  104. while(start&&(len = fileOutStream.read(buffer)) != -1){
  105. outStream.write(buffer, 0, len);
  106. length += len;
  107. Message msg = new Message();
  108. msg.getData().putInt("size", length);
  109. handler.sendMessage(msg);
  110. }
  111. fileOutStream.close();
  112. outStream.close();
  113. inStream.close();
  114. socket.close();
  115. if(length==uploadFile.length()) logService.delete(uploadFile);
  116. } catch (Exception e) {
  117. e.printStackTrace();
  118. }
  119. }
  120. }).start();
  121. }
  122. }
  123. StreamTool.java
  124. package com.android.socket.utils;
  125. import java.io.ByteArrayOutputStream;
  126. import java.io.File;
  127. import java.io.FileOutputStream;
  128. import java.io.IOException;
  129. import java.io.InputStream;
  130. import java.io.PushbackInputStream;
  131. public class StreamTool {
  132. public static void save(File file, byte[] data) throws Exception {
  133. FileOutputStream outStream = new FileOutputStream(file);
  134. outStream.write(data);
  135. outStream.close();
  136. }
  137. public static String readLine(PushbackInputStream in) throws IOException {
  138. char buf[] = new char[128];
  139. int room = buf.length;
  140. int offset = 0;
  141. int c;
  142. loop:       while (true) {
  143. switch (c = in.read()) {
  144. case -1:
  145. case '\n':
  146. break loop;
  147. case '\r':
  148. int c2 = in.read();
  149. if ((c2 != '\n') && (c2 != -1)) in.unread(c2);
  150. break loop;
  151. default:
  152. if (--room < 0) {
  153. char[] lineBuffer = buf;
  154. buf = new char[offset + 128];
  155. room = buf.length - offset - 1;
  156. System.arraycopy(lineBuffer, 0, buf, 0, offset);
  157. }
  158. buf[offset++] = (char) c;
  159. break;
  160. }
  161. }
  162. if ((c == -1) && (offset == 0)) return null;
  163. return String.copyValueOf(buf, 0, offset);
  164. }
  165. /**
  166. * 读取流
  167. * @param inStream
  168. * @return 字节数组
  169. * @throws Exception
  170. */
  171. public static byte[] readStream(InputStream inStream) throws Exception{
  172. ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
  173. byte[] buffer = new byte[1024];
  174. int len = -1;
  175. while( (len=inStream.read(buffer)) != -1){
  176. outSteam.write(buffer, 0, len);
  177. }
  178. outSteam.close();
  179. inStream.close();
  180. return outSteam.toByteArray();
  181. }
  182. }
  183. UploadLogService.java
  184. package com.android.service;
  185. import java.io.File;
  186. import android.content.Context;
  187. import android.database.Cursor;
  188. import android.database.sqlite.SQLiteDatabase;
  189. public class UploadLogService {
  190. private DBOpenHelper dbOpenHelper;
  191. public UploadLogService(Context context){
  192. this.dbOpenHelper = new DBOpenHelper(context);
  193. }
  194. public void save(String sourceid, File uploadFile){
  195. SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
  196. db.execSQL("insert into uploadlog(uploadfilepath, sourceid) values(?,?)",
  197. new Object[]{uploadFile.getAbsolutePath(),sourceid});
  198. }
  199. public void delete(File uploadFile){
  200. SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
  201. db.execSQL("delete from uploadlog where uploadfilepath=?", new Object[]{uploadFile.getAbsolutePath()});
  202. }
  203. public String getBindId(File uploadFile){
  204. SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
  205. Cursor cursor = db.rawQuery("select sourceid from uploadlog where uploadfilepath=?",
  206. new String[]{uploadFile.getAbsolutePath()});
  207. if(cursor.moveToFirst()){
  208. return cursor.getString(0);
  209. }
  210. return null;
  211. }
  212. }
  213. DBOpenHelper.java
  214. package com.android.service;
  215. import android.content.Context;
  216. import android.database.sqlite.SQLiteDatabase;
  217. import android.database.sqlite.SQLiteOpenHelper;
  218. public class DBOpenHelper extends SQLiteOpenHelper {
  219. public DBOpenHelper(Context context) {
  220. super(context, "upload.db", null, 1);
  221. }
  222. @Override
  223. public void onCreate(SQLiteDatabase db) {
  224. db.execSQL("CREATE TABLE uploadlog (_id integer primary key autoincrement, uploadfilepath varchar(100), sourceid varchar(10))");
  225. }
  226. @Override
  227. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  228. db.execSQL("DROP TABLE IF EXISTS uploadlog");
  229. onCreate(db);
  230. }
  231. }
  232. main.xml
  233. <?xml version="1.0" encoding="utf-8"?>
  234. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  235. android:orientation="vertical"
  236. android:layout_width="fill_parent"
  237. android:layout_height="fill_parent"
  238. >
  239. <TextView
  240. android:layout_width="fill_parent"
  241. android:layout_height="wrap_content"
  242. android:text="@string/filename"
  243. />
  244. <EditText
  245. android:layout_width="fill_parent"
  246. android:layout_height="wrap_content"
  247. android:text="022.jpg"
  248. android:id="@+id/filename"
  249. />
  250. <Button
  251. android:layout_width="wrap_content"
  252. android:layout_height="wrap_content"
  253. android:text="@string/button"
  254. android:id="@+id/button"
  255. />
  256. <Button
  257. android:layout_width="wrap_content"
  258. android:layout_height="wrap_content"
  259. android:text="暂停"
  260. android:id="@+id/stop"
  261. />
  262. <ProgressBar
  263. android:layout_width="fill_parent"
  264. android:layout_height="20px"
  265. style="?android:attr/progressBarStyleHorizontal"
  266. android:id="@+id/uploadbar"
  267. />
  268. <TextView
  269. android:layout_width="fill_parent"
  270. android:layout_height="wrap_content"
  271. android:gravity="center"
  272. android:id="@+id/result"
  273. />
  274. </LinearLayout>
  275. AndroidManifest.xml
  276. <?xml version="1.0" encoding="utf-8"?>
  277. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  278. package="com.android.upload"
  279. android:versionCode="1"
  280. android:versionName="1.0" >
  281. <uses-sdk android:minSdkVersion="8" />
  282. <application
  283. android:icon="@drawable/ic_launcher"
  284. android:label="@string/app_name" >
  285. <activity
  286. android:name=".UploadActivity"
  287. android:label="@string/app_name" >
  288. <intent-filter>
  289. <action android:name="android.intent.action.MAIN" />
  290. <category android:name="android.intent.category.LAUNCHER" />
  291. </intent-filter>
  292. </activity>
  293. </application>
  294. <!-- 访问网络的权限 -->
  295. <uses-permission android:name="android.permission.INTERNET"/>
  296. <!-- 在SDCard中创建与删除文件权限 -->
  297. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
  298. <!-- 往SDCard写入数据权限 -->
  299. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  300. </manifest>

Java服务端:

  1. SocketServer.javapackage com.android.socket.server;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.OutputStream;
  7. import java.io.PushbackInputStream;
  8. import java.io.RandomAccessFile;
  9. import java.net.ServerSocket;
  10. import java.net.Socket;
  11. import java.text.SimpleDateFormat;
  12. import java.util.Date;
  13. import java.util.HashMap;
  14. import java.util.Map;
  15. import java.util.Properties;
  16. import java.util.concurrent.ExecutorService;
  17. import java.util.concurrent.Executors;
  18. import com.android.socket.utils.StreamTool;
  19. public class SocketServer {
  20. private String uploadPath="D:/uploadFile/";
  21. private ExecutorService executorService;// 线程池
  22. private ServerSocket ss = null;
  23. private int port;// 监听端口
  24. private boolean quit;// 是否退出
  25. private Map<Long, FileLog> datas = new HashMap<Long, FileLog>();// 存放断点数据,最好改为数据库存放
  26. public SocketServer(int port) {
  27. this.port = port;
  28. // 初始化线程池
  29. executorService = Executors.newFixedThreadPool(Runtime.getRuntime()
  30. .availableProcessors() * 50);
  31. }
  32. // 启动服务
  33. public void start() throws Exception {
  34. ss = new ServerSocket(port);
  35. while (!quit) {
  36. Socket socket = ss.accept();// 接受客户端的请求
  37. // 为支持多用户并发访问,采用线程池管理每一个用户的连接请求
  38. executorService.execute(new SocketTask(socket));// 启动一个线程来处理请求
  39. }
  40. }
  41. // 退出
  42. public void quit() {
  43. this.quit = true;
  44. try {
  45. ss.close();
  46. } catch (IOException e) {
  47. e.printStackTrace();
  48. }
  49. }
  50. public static void main(String[] args) throws Exception {
  51. SocketServer server = new SocketServer(7878);
  52. server.start();
  53. }
  54. private class SocketTask implements Runnable {
  55. private Socket socket;
  56. public SocketTask(Socket socket) {
  57. this.socket = socket;
  58. }
  59. @Override
  60. public void run() {
  61. try {
  62. System.out.println("accepted connenction from "
  63. + socket.getInetAddress() + " @ " + socket.getPort());
  64. PushbackInputStream inStream = new PushbackInputStream(
  65. socket.getInputStream());
  66. // 得到客户端发来的第一行协议数据:Content-Length=143253434;filename=xxx.3gp;sourceid=
  67. // 如果用户初次上传文件,sourceid的值为空。
  68. String head = StreamTool.readLine(inStream);
  69. System.out.println(head);
  70. if (head != null) {
  71. // 下面从协议数据中读取各种参数值
  72. String[] items = head.split(";");
  73. String filelength = items[0].substring(items[0].indexOf("=") + 1);
  74. String filename = items[1].substring(items[1].indexOf("=") + 1);
  75. String sourceid = items[2].substring(items[2].indexOf("=") + 1);
  76. Long id = System.currentTimeMillis();
  77. FileLog log = null;
  78. if (null != sourceid && !"".equals(sourceid)) {
  79. id = Long.valueOf(sourceid);
  80. log = find(id);//查找上传的文件是否存在上传记录
  81. }
  82. File file = null;
  83. int position = 0;
  84. if(log==null){//如果上传的文件不存在上传记录,为文件添加跟踪记录
  85. String path = new SimpleDateFormat("yyyy/MM/dd/HH/mm").format(new Date());
  86. File dir = new File(uploadPath+ path);
  87. if(!dir.exists()) dir.mkdirs();
  88. file = new File(dir, filename);
  89. if(file.exists()){//如果上传的文件发生重名,然后进行改名
  90. filename = filename.substring(0, filename.indexOf(".")-1)+ dir.listFiles().length+ filename.substring(filename.indexOf("."));
  91. file = new File(dir, filename);
  92. }
  93. save(id, file);
  94. }else{// 如果上传的文件存在上传记录,读取上次的断点位置
  95. file = new File(log.getPath());//从上传记录中得到文件的路径
  96. if(file.exists()){
  97. File logFile = new File(file.getParentFile(), file.getName()+".log");
  98. if(logFile.exists()){
  99. Properties properties = new Properties();
  100. properties.load(new FileInputStream(logFile));
  101. position = Integer.valueOf(properties.getProperty("length"));//读取断点位置
  102. }
  103. }
  104. }
  105. OutputStream outStream = socket.getOutputStream();
  106. String response = "sourceid="+ id+ ";position="+ position+ "\r\n";
  107. //服务器收到客户端的请求信息后,给客户端返回响应信息:sourceid=1274773833264;position=0
  108. //sourceid由服务生成,唯一标识上传的文件,position指示客户端从文件的什么位置开始上传
  109. outStream.write(response.getBytes());
  110. RandomAccessFile fileOutStream = new RandomAccessFile(file, "rwd");
  111. if(position==0) fileOutStream.setLength(Integer.valueOf(filelength));//设置文件长度
  112. fileOutStream.seek(position);//移动文件指定的位置开始写入数据
  113. byte[] buffer = new byte[1024];
  114. int len = -1;
  115. int length = position;
  116. while( (len=inStream.read(buffer)) != -1){//从输入流中读取数据写入到文件中
  117. fileOutStream.write(buffer, 0, len);
  118. length += len;
  119. Properties properties = new Properties();
  120. properties.put("length", String.valueOf(length));
  121. FileOutputStream logFile = new FileOutputStream(new File(file.getParentFile(), file.getName()+".log"));
  122. properties.store(logFile, null);//实时记录文件的最后保存位置
  123. logFile.close();
  124. }
  125. if(length==fileOutStream.length()) delete(id);
  126. fileOutStream.close();
  127. inStream.close();
  128. outStream.close();
  129. file = null;
  130. }
  131. } catch (Exception e) {
  132. e.printStackTrace();
  133. } finally {
  134. try {
  135. if(socket != null && !socket.isClosed()) socket.close();
  136. } catch (IOException e) {}
  137. }
  138. }
  139. }
  140. public FileLog find(Long sourceid) {
  141. return datas.get(sourceid);
  142. }
  143. // 保存上传记录
  144. public void save(Long id, File saveFile) {
  145. // 日后可以改成通过数据库存放
  146. datas.put(id, new FileLog(id, saveFile.getAbsolutePath()));
  147. }
  148. // 当文件上传完毕,删除记录
  149. public void delete(long sourceid) {
  150. if (datas.containsKey(sourceid))
  151. datas.remove(sourceid);
  152. }
  153. private class FileLog {
  154. private Long id;
  155. private String path;
  156. public FileLog(Long id, String path) {
  157. super();
  158. this.id = id;
  159. this.path = path;
  160. }
  161. public Long getId() {
  162. return id;
  163. }
  164. public void setId(Long id) {
  165. this.id = id;
  166. }
  167. public String getPath() {
  168. return path;
  169. }
  170. public void setPath(String path) {
  171. this.path = path;
  172. }
  173. }
  174. }
  175. ServerWindow.javapackage com.android.socket.server;
  176. import java.awt.BorderLayout;
  177. import java.awt.Frame;
  178. import java.awt.Label;
  179. import java.awt.event.WindowEvent;
  180. import java.awt.event.WindowListener;
  181. public class ServerWindow extends Frame{
  182. private SocketServer server;
  183. private Label label;
  184. public ServerWindow(String title){
  185. super(title);
  186. server = new SocketServer(7878);
  187. label = new Label();
  188. add(label, BorderLayout.PAGE_START);
  189. label.setText("服务器已经启动");
  190. this.addWindowListener(new WindowListener() {
  191. @Override
  192. public void windowOpened(WindowEvent e) {
  193. new Thread(new Runnable() {
  194. @Override
  195. public void run() {
  196. try {
  197. server.start();
  198. } catch (Exception e) {
  199. e.printStackTrace();
  200. }
  201. }
  202. }).start();
  203. }
  204. @Override
  205. public void windowIconified(WindowEvent e) {
  206. }
  207. @Override
  208. public void windowDeiconified(WindowEvent e) {
  209. }
  210. @Override
  211. public void windowDeactivated(WindowEvent e) {
  212. }
  213. @Override
  214. public void windowClosing(WindowEvent e) {
  215. server.quit();
  216. System.exit(0);
  217. }
  218. @Override
  219. public void windowClosed(WindowEvent e) {
  220. }
  221. @Override
  222. public void windowActivated(WindowEvent e) {
  223. }
  224. });
  225. }
  226. /**
  227. * @param args
  228. */
  229. public static void main(String[] args) {
  230. ServerWindow window = new ServerWindow("文件上传服务端");
  231. window.setSize(300, 300);
  232. window.setVisible(true);
  233. }
  234. }
  235. StreamTool.javapackage com.android.socket.utils;
  236. import java.io.ByteArrayOutputStream;
  237. import java.io.File;
  238. import java.io.FileOutputStream;
  239. import java.io.IOException;
  240. import java.io.InputStream;
  241. import java.io.PushbackInputStream;
  242. public class StreamTool {
  243. public static void save(File file, byte[] data) throws Exception {
  244. FileOutputStream outStream = new FileOutputStream(file);
  245. outStream.write(data);
  246. outStream.close();
  247. }
  248. public static String readLine(PushbackInputStream in) throws IOException {
  249. char buf[] = new char[128];
  250. int room = buf.length;
  251. int offset = 0;
  252. int c;
  253. loop:       while (true) {
  254. switch (c = in.read()) {
  255. case -1:
  256. case '\n':
  257. break loop;
  258. case '\r':
  259. int c2 = in.read();
  260. if ((c2 != '\n') && (c2 != -1)) in.unread(c2);
  261. break loop;
  262. default:
  263. if (--room < 0) {
  264. char[] lineBuffer = buf;
  265. buf = new char[offset + 128];
  266. room = buf.length - offset - 1;
  267. System.arraycopy(lineBuffer, 0, buf, 0, offset);
  268. }
  269. buf[offset++] = (char) c;
  270. break;
  271. }
  272. }
  273. if ((c == -1) && (offset == 0)) return null;
  274. return String.copyValueOf(buf, 0, offset);
  275. }
  276. /**
  277. * 读取流
  278. * @param inStream
  279. * @return 字节数组
  280. * @throws Exception
  281. */
  282. public static byte[] readStream(InputStream inStream) throws Exception{
  283. ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
  284. byte[] buffer = new byte[1024];
  285. int len = -1;
  286. while( (len=inStream.read(buffer)) != -1){
  287. outSteam.write(buffer, 0, len);
  288. }
  289. outSteam.close();
  290. inStream.close();
  291. return outSteam.toByteArray();
  292. }
  293. }

运行效果如下:
Android前端控制:

后台监控日志:

下载后的文件路径:

源码下载地址

Android中Socket大文件断点上传的更多相关文章

  1. Android应用开发之使用Socket进行大文件断点上传续传

    http://www.linuxidc.com/Linux/2012-03/55567.htm http://blog.csdn.net/shimiso/article/details/8529633 ...

  2. asp.net 如何实现大文件断点上传功能?

    之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目中,不论是用户头像上传,还是各种媒体文件的上传,以及各种个性的业务需 ...

  3. 大文件断点上传 js+php

    /* * js */ function PostFile(file, i, t) {    console.log(1);  var name = file.name, //文件名 size = fi ...

  4. ASP.NET大文件断点上传

    HTML部分 <%@PageLanguage="C#"AutoEventWireup="true"CodeBehind="index.aspx. ...

  5. 在React中使用WebUploader实现大文件分片上传的踩坑日记!

    前段时间公司项目有个大文件分片上传的需求,项目是用React写的,大文件分片上传这个功能使用了WebUploader这个组件. 具体交互是: 1. 点击上传文件button后出现弹窗,弹窗内有选择文件 ...

  6. Webuploader 大文件分片上传

    百度Webuploader 大文件分片上传(.net接收)   前阵子要做个大文件上传的功能,找来找去发现Webuploader还不错,关于她的介绍我就不再赘述. 动手前,在园子里找到了一篇不错的分片 ...

  7. Hadoop如何将TB级大文件的上传性能优化上百倍?

    这篇文章,我们来看看,Hadoop的HDFS分布式文件系统的文件上传的性能优化. 首先,我们还是通过一张图来回顾一下文件上传的大概的原理. 由上图所示,文件上传的原理,其实说出来也简单. 比如有个TB ...

  8. iOS大文件分片上传和断点续传

    总结一下大文件分片上传和断点续传的问题.因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况.http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件 ...

  9. 使用webuploader组件实现大文件分片上传,断点续传

    本人在2010年时使用swfupload为核心进行文件的批量上传的解决方案.见文章:WEB版一次选择多个文件进行批量上传(swfupload)的解决方案. 本人在2013年时使用plupload为核心 ...

随机推荐

  1. Innodb 锁系列1 同步机制

    同步机制 Innodb实现了不依赖于平台的mutex,rwlock. 1. 全局变量 对于mutex, rwlock,都有一个全局链表. 1. mutex全局链表:mutex_list 2. rwlo ...

  2. (转载)Web存储和SessionStorage locaStorage

    <转> sessionStorage 和 localStorage 是HTML5 Web Storage API 提供的,可以方便的在web请求之间保存数据.有了本地数据,就可以避免数据在 ...

  3. Jquery Ashx 存在缓存问题

    因为缓存总是不调用 PermissionEdit.ashx $.ajax({ type: "get", cache: false, url:"PermissionEdit ...

  4. POJ 2455 Secret Milking Machine (二分+无向图最大流)

    [题意]n个点的一个无向图,在保证存在T条从1到n的不重复路径(任意一条边都不能重复)的前提下,要使得这t条路上经过的最长路径最短. 之所以把"经过的最长路径最短"划个重点是因为前 ...

  5. Spring AOP--基于XML文件的配置

    Spring AOP的配置可以基于注解,也可以基于XML文件.前面几篇都是使用注解的方式.下面介绍下使用XML文件如何配置 使用的测试类和切面类都类似.只需要属于AOP的注解去掉即可.下面是AOP的X ...

  6. Application Pool Identities

    Whether you are running your site on your own server or in the cloud, security must be at the top of ...

  7. 数学(扩展欧几里得算法):HDU 5114 Collision

    Matt is playing a naive computer game with his deeply loved pure girl. The playground is a rectangle ...

  8. HDU 4009 Transfer water 最小树形图

    分析:建一个远点,往每个点连建井的价值(单向边),其它输水线按照题意建单向边 然后以源点为根的权值最小的有向树就是答案,套最小树形图模板 #include <iostream> #incl ...

  9. Flash 导出图片和声音

    命令文件 PolarBear_jsfl.zip Flash Professional 编辑器命令,用来导出 flash 库中的图片和声音 使用步骤: 1. 首先下载 PolarBear_jsfl.zi ...

  10. 【原创】lua编译时发现缺少readline库

    编译lualua项目,其中用到了lua-5.1版本的源码,编译时提示缺少readline库,找不到readline/readline.h头文件等 发现系统中其实有安装readline库不过没有做链接和 ...