文章目录
- 前言
- 一、Socket是什么?
- 二、代码实现通信
- 总结
前言
作为一个合格的程序员,不能不懂网络编程,说到网络编程,Socket编程作为网络通信的底层API,对我们了解那些网络框架的底层原理,大有助益。
一、Socket是什么?
Socket是TCP/IP协议中应用层和传输层之间的媒介,Socket本质上就是对TCP/IP的运用进行了一次封装,以便供应用层使用。应用程序直接使用Socket API 就可以进行通信。
二、代码实现通信
本文主要是用Java客户端向服务器发送请求,获取响应信息。Socket的客户端和服务器之间的连接和TCP连接的“三次招手”差不多。客户端和服务器是通过字节流的形式就行通信的。
1.先创建一个HttpResponse类,以存放响应信息的各个部分。
public class HttpResponse {
private String url;
private String header;
private String body;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getHeader() {
return header;
}
public void setHeader(String header) {
this.header = header;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
@Override
public String toString() {
return "HttpResponse{" +
"url='" + url + '\'' +
", header='" + header + '\'' +
", body='" + body + '\'' +
'}';
}
}
2.实现客户端通信
public class TcpClient {
public static void main(String[] args) throws IOException {
Socket socket = null;
OutputStream out = null;
InputStream in = null;
ByteArrayOutputStream byteOut = null;
try {
//服务器ip地址和端口
socket = new Socket("www.baidu.com",80);
//输出流
out = socket.getOutputStream();
//构造http请求
StringBuilder builder = new StringBuilder();
//header信息
Map<String,String> map = new HashMap<>();
//文本类型
map.put("Content-Type","text/html;charset=utf-8");
//保持连接
map.put("Connection","keep-alive");
map.put("Host","www.baidu.com");
//请求行
builder.append("GET / HTTP/1.1\r\n");
//请求头部
for(Map.Entry<String,String> entry:map.entrySet()){
builder.append(entry.getKey() + ":" +entry.getValue() + "\r\n");
}
//请求空行
builder.append("\r\n");
out.write(builder.toString().getBytes());
//输入流
in = socket.getInputStream();
byteOut = new ByteArrayOutputStream();
byte[] bytes = new byte[1024];
int len = -1;
while ((len = in.read(bytes)) != -1){
//写入新建流中
byteOut.write(bytes,0,len);
}
//以响应空行为标志,将响应信息分为两个部分
String[] str = new String(byteOut.toByteArray()).split("\r\n\r\n");
//以空行为标志,将响应行和响应头部分开
String[] urlAndHeader = str[0].split("\r\n");
HttpResponse httpResponse = new HttpResponse();
//响应行
httpResponse.setUrl(urlAndHeader[0]);
StringBuilder headers = new StringBuilder();
for (int i = 1; i < urlAndHeader.length; i++){
//拼接响应头部
headers.append(urlAndHeader[i] + "\r\n");
}
//响应头部
httpResponse.setHeader(headers.toString());
//响应文本
httpResponse.setBody(str[1]);
System.out.println(httpResponse.toString());
} catch (IOException e) {
e.printStackTrace();
}finally {
if (byteOut != null){
byteOut.close();
}
if (out != null){
out.close();
}
if (in != null){
in.close();
}
if (socket != null){
//释放资源
socket.close();
}
}
}
}
总结
这就是实现Socket通信的一个简单例子,我们经常使用的开源框架,如Java提供的HttpURLConnection与 HttpClient,以及OKHttp网络框架底层都是基于Socket编程实现的。因此了解Socket编程是很有必要的。