HTTP协议是TCP/IP协议之上应用层的协议。
至于WebSocket协议是什么鬼可以看这篇知乎。WebSocket长连接协议以及与HTTP协议的区别
还是先看看HTTP1.1的协议是怎么玩耍的吧。
HTTP报文的组成部分
- 起始行(start line)
- 首部(header)
- 主体(body)
HTTP普通的POST和文件的POST之间的存在差异的,具体可以看这篇文章——Multipart/form-data POST文件上传详解,写的还是蛮详细的。
我们只要在iOS代码中组织这样的HTTP报文就可以实现多文本的上传啦。
下面是一段标准的文件上传报文
//HTTP 头 开始
Content-Type: multipart/form-data, boundary=niusige
--niusige
content-disposition: form-data; name="field1"
Hello World!
--niusige
content-disposition: form-data; name="pic"; filename="duolaameng.jpg"
balabala...NSData of the Image
--niusige--
第一行指明了Content-Type和boundary,boundary在浏览器的上传中一般是自动生成的,比较复杂而不会在其他部分出现,这里只是一个模拟,所以取得比较简单。
然后以boundary为标志做待上传字段的分割。
以下是我写的图片上传的一段代码,借了Alamofire库,谁叫人家这么方便呢。
let boundary = "niusige"
let URL = NSURL(string: BASE_API)!
let request = NSMutableURLRequest(URL: URL)
request.HTTPMethod = "POST"
request.addValue("multipart/form-data; boundary=" + boundary, forHTTPHeaderField: "Content-Type")
let params = ["uid": "3", "token": "xxxxxxxxxxxxxxxxxxxxxxxx"]
let data = NSMutableData()
for (key, value) in params {
data.appendData("--\(boundary)\r\n".nsdata)
data.appendData("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".nsdata)
data.appendData("\(value)\r\n".nsdata)
}
data.appendData("--\(boundary)\r\n".nsdata)
data.appendData("Content-Disposition: form-data; name=\"data\"; filename=\"avatar.jpg\"\r\n\r\n".nsdata)
let image = UIImage(named: "wordify.jpg")
let imageData = UIImageJPEGRepresentation(image, 0.2)
data.appendData(imageData)
data.appendData("\r\n".nsdata)
data.appendData("--\(boundary)--\r\n".nsdata)
// URLRequestConvertible and NSData
Alamofire.upload(request, data).progress {
(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite) in
println("\(totalBytesWritten) / \(totalBytesExpectedToWrite)")
}.responseJSON {
(request, response, JSON, error) in
println(request)
println(response)
println(JSON)
println(error)
}
好啦,文件上传就完成啦,是不是很简单。
感觉我接下来会看看NSURLConnection和NSURLSession,从 NSURLConnection 到 NSURLSession,然后去探索下长连接WebSocket协议,估计会蛮有趣的。