目录
一、TCP
面向链接的传输协议,可无差错的数据传输,双向字节流的传递
服务端:
1.首先定义接受信息的端口,并且进入阻塞状态,等待消息到来。
ServerSocket ss=new ServerSocket(8001); //驻守在8001端口
Socket s=ss.accept();
2.打开输入输出流:
InputStream ips=s.getInputStream(); //有人连上来,打开输入流
OutputStream ops=s.getOutputStream(); //打开输出流
3.1输出消息给客户端
ops.write("Hello, Client!".getBytes());
3.2接受客户端的消息
BufferedReader br = new BufferedReader(new InputStreamReader(ips));
利用br.readline()来读取数据。
客户端:
1.链接服务端:Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 8001);
2.开启输入输出流
InputStream ips = s.getInputStream(); //开启通道的输入流
BufferedReader brNet = new BufferedReader(new InputStreamReader(ips));
OutputStream ops = s.getOutputStream(); //开启通道的输出流
DataOutputStream dos = new DataOutputStream(ops);//让二进制写入
3.通过brNet.readLine()读消息,dos.writeBytes()发送消息
import java.net.*;
import java.io.*;
public class TcpServer
{
public static void main(String [] args)
{
try
{
ServerSocket ss=new ServerSocket(8001); //驻守在8001端口
Socket s=ss.accept(); //阻塞,等到有客户端连接上来
System.out.println("welcome to the java world");
InputStream ips=s.getInputStream(); //有人连上来,打开输入流
OutputStream ops=s.getOutputStream(); //打开输出流
//同一个通道,服务端的输出流就是客户端的输入流;服务端的输入流就是客户端的输出流
ops.write("Hello, Client!".getBytes()); //输出一句话给客户端
BufferedReader br = new BufferedReader(new InputStreamReader(ips));
//从客户端读取一句话
System.out.println("Client said: " + br.readLine());
ips.close();
ops.close();
s.close();
ss.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
import java.net.*;
import java.io.*;
public class TcpClient {
public static void main(String[] args) {
try {
Socket s = new Socket(InetAddress.getByName("127.0.0.1"), 8001); //需要服务端先开启
//同一个通道,服务端的输出流就是客户端的输入流;服务端的输入流就是客户端的输出流
InputStream ips = s.getInputStream(); //开启通道的输入流
BufferedReader brNet = new BufferedReader(new InputStreamReader(ips));
OutputStream ops = s.getOutputStream(); //开启通道的输出流
DataOutputStream dos = new DataOutputStream(ops);//让二进制写入
BufferedReader brKey = new BufferedReader(new InputStreamReader(System.in));//将输入流改成控制台输入如
while (true)
{
String strWord = brKey.readLine();
if (strWord.equalsIgnoreCase("quit"))//当输入的时quit时则跳出循环5142
{
break;
}
else
{
System.out.println("I want to send: " + strWord);
dos.writeBytes(strWord + System.getProperty("line.separator"));
System.out.println("Server said: " + brNet.readLine());
}
}
dos.close();
brNet.close();
brKey.close();
s.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
二、UDP
面向无链接的传输协议,不可靠的数据传输,速度快。
如果a向b发送信息,若b不在,那么发送的信息就丢失了。
方法:
1.用DatagramSocket来建立通讯管道,send和receive方法来发送和接收信息。
2.发送信息和接受信息时都是需要用类DatagramPacket来封装/解封装数据。
所见即所得:
import java.net.*;
public class UdpRecv
{
public static void main(String[] args) throws Exception
{
DatagramSocket ds=new DatagramSocket(3000);//在本机的3000端口上接收消息
byte [] buf=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf,1024);//将消息进行装箱
System.out.println("UdpRecv: 我在等待信息");
ds.receive(dp);
System.out.println("UdpRecv: 我接收到信息");
String strRecv=new String(dp.getData(),0,dp.getLength()) +
" from " + dp.getAddress().getHostAddress()+":"+dp.getPort();
System.out.println(strRecv);
Thread.sleep(1000);
System.out.println("UdpRecv: 我要发送信息");
String str="hello world 222";
DatagramPacket dp2=new DatagramPacket(str.getBytes(),str.length(),
InetAddress.getByName("127.0.0.1"),dp.getPort());//dp.getPort()获取对方的端口
ds.send(dp2);
System.out.println("UdpRecv: 我发送信息结束");
ds.close();
}
}
import java.net.*;
public class UdpSend
{
public static void main(String [] args) throws Exception
{
DatagramSocket ds=new DatagramSocket();
String str="hello world";
DatagramPacket dp=new DatagramPacket(str.getBytes(),str.length(),
InetAddress.getByName("127.0.0.1"),3000);//
System.out.println("UdpSend: 我要发送信息");
ds.send(dp);
System.out.println("UdpSend: 我发送信息结束");
Thread.sleep(1000);
byte [] buf=new byte[1024];
DatagramPacket dp2=new DatagramPacket(buf,1024);
System.out.println("UdpSend: 我在等待信息");
ds.receive(dp2);
System.out.println("UdpSend: 我接收到信息");
String str2=new String(dp2.getData(),0,dp2.getLength()) +
" from " + dp2.getAddress().getHostAddress()+":"+dp2.getPort();
System.out.println(str2);
ds.close();
}
}
三、HTTP编程
主要分为get和post方法
get从服务器端获取资源到客户端来
1.首先定义URL网址
String urlName = "http://www.baidu.com";
URL url = new URL(urlName);
2.打开连接
URLConnection connection = url.openConnection();
connection.connect();
3.读出网页内容:
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
再用br.readeline()读出。
/*
* 直接获取结果
*/
import java.io.*;
import java.net.*;
import java.util.*;
public class URLConnectionGetTest
{
public static void main(String[] args)
{
try
{
String urlName = "http://www.baidu.com";
URL url = new URL(urlName);
URLConnection connection = url.openConnection();
connection.connect();
// 打印http的头部信息
Map<String, List<String>> headers = connection.getHeaderFields();
for (Map.Entry<String, List<String>> entry : headers.entrySet())
{
String key = entry.getKey();
for (String value : entry.getValue())
System.out.println(key + ": " + value);
}
// 输出将要收到的内容属性信息
System.out.println("----------");
System.out.println("getContentType: " + connection.getContentType());
System.out.println("getContentLength: " + connection.getContentLength());
System.out.println("getContentEncoding: " + connection.getContentEncoding());
System.out.println("getDate: " + connection.getDate());
System.out.println("getExpiration: " + connection.getExpiration());
System.out.println("getLastModifed: " + connection.getLastModified());
System.out.println("----------");
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
// 输出收到的内容
String line = "";
while((line=br.readLine()) != null)
{
System.out.println(line);
}
br.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
post载入参数到服务器端,然后再读取进来
1.首先定义网址和属性
2.进行字符串的凭借使参数输入
3.判断访问的是否成功
4.读取网页服务端的资源//
/*
* 提交参数获取结果
*/
import java.io.*;
import java.net.*;
import java.nio.file.*;
import java.util.*;
public class URLConnectionPostTest
{
public static void main(String[] args) throws IOException
{
String urlString = "https://tools.usps.com/go/ZipLookupAction.action";
Object userAgent = "HTTPie/0.9.2";//定义属性
Object redirects = "1";//定义属性
CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));//接受所有cookie
Map<String, String> params = new HashMap<String, String>();
params.put("tAddress", "1 Market Street"); //输入参数
params.put("tCity", "San Francisco");
params.put("sState", "CA");
//dppost函数完成网页提交访问
String result = doPost(new URL(urlString), params,
userAgent == null ? null : userAgent.toString(),
redirects == null ? -1 : Integer.parseInt(redirects.toString()));//Integer.parseInt将字符串整数
System.out.println(result);
}
public static String doPost(URL url, Map<String, String> nameValuePairs, String userAgent, int redirects)
throws IOException
{
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//设置属性
if (userAgent != null)
connection.setRequestProperty("User-Agent", userAgent);
if (redirects >= 0)
connection.setInstanceFollowRedirects(false);
connection.setDoOutput(true);//时服务器可以输出打开,可以被写入
//输出请求的参数
try (PrintWriter out = new PrintWriter(connection.getOutputStream()))
{
boolean first = true;
//拼接所有的参数
for (Map.Entry<String, String> pair : nameValuePairs.entrySet())
{
//参数必须这样拼接 a=1&b=2&c=3
if (first)
{
first = false;
}
else
{
out.print('&');
}
String name = pair.getKey();
String value = pair.getValue();
out.print(name);
out.print('=');
out.print(URLEncoder.encode(value, "UTF-8"));//因为value中间含有空格最好使用UTF-8加密转义
}
}
String encoding = connection.getContentEncoding();
if (encoding == null)
{
encoding = "UTF-8";
}
if (redirects > 0)
{
int responseCode = connection.getResponseCode();//获取返回码
System.out.println("responseCode: " + responseCode);
if (responseCode == HttpURLConnection.HTTP_MOVED_PERM
|| responseCode == HttpURLConnection.HTTP_MOVED_TEMP
|| responseCode == HttpURLConnection.HTTP_SEE_OTHER)
{
String location = connection.getHeaderField("Location");
if (location != null)
{
URL base = connection.getURL();
connection.disconnect();
return doPost(new URL(base, location), nameValuePairs, userAgent, redirects - 1);
}
}
}
else if (redirects == 0)
{
throw new IOException("Too many redirects");
}
//接下来获取html 内容
StringBuilder response = new StringBuilder();
//获取内容
try (Scanner in = new Scanner(connection.getInputStream(), encoding))
{
while (in.hasNextLine())
{
response.append(in.nextLine());
response.append("\n");
}
}
catch (IOException e)
{
InputStream err = connection.getErrorStream();
if (err == null) throw e;
try (Scanner in = new Scanner(err))
{
response.append(in.nextLine());
response.append("\n");
}
}
return response.toString();
}
}
四、补充httpClient类
1.使用自带jdk自带的httpClient类,但是需要jdk9以上才可以支持
/*
* 相当于上例get函数,不同的方法实现同一个功能
*/
import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.Charset;
public class JDKHttpClientGetTest {
public static void main(String[] args) throws IOException, InterruptedException {
doGet();
}
public static void doGet() {
try{
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(URI.create("http://www.baidu.com")).build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());//服务器对我们响应
System.out.println(response.body());
}
catch(Exception e) {
e.printStackTrace();
}
}
}
/*
* 相当于上例的post函数,不同的方法实现同一个功能
*/
import java.io.IOException;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class JDKHttpClientPostTest {
public static void main(String[] args) throws IOException, InterruptedException {
doPost();
}
public static void doPost() {
try {
HttpClient client = HttpClient.newBuilder().build();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://tools.usps.com/go/ZipLookupAction.action"))//网址
//.header("Content-Type","application/x-www-form-urlencoded")
.header("User-Agent", "HTTPie/0.9.2")//属性
.header("Content-Type","application/x-www-form-urlencoded;charset=utf-8")//属性
//.method("POST", HttpRequest.BodyPublishers.ofString("tAddress=1 Market Street&tCity=San Francisco&sState=CA"))
//.version(Version.HTTP_1_1)
//定义参数,并且加密
.POST(HttpRequest.BodyPublishers.ofString("tAddress="
+ URLEncoder.encode("1 Market Street", "UTF-8")
+ "&tCity=" + URLEncoder.encode("San Francisco", "UTF-8") + "&sState=CA"))
//.POST(HttpRequest.BodyPublishers.ofString("tAddress=" + URLEncoder.encode("1 Market Street", "UTF-8") + "&tCity=" + URLEncoder.encode("San Francisco", "UTF-8") + "&sState=CA"))
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());//提交之后获取返回值
System.out.println(response.statusCode());
System.out.println(response.headers());
System.out.println(response.body().toString());
}
catch(Exception e) {
e.printStackTrace();
}
}
}
2.使用第三方库
是httpClient进化来的,
第三方库依赖是:
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
import java.io.*;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class HttpComponentsGetTest {
public final static void main(String[] args) throws Exception {
CloseableHttpClient httpClient = HttpClients.createDefault();
RequestConfig requestConfig = RequestConfig.custom()
.setConnectTimeout(5000) //设置连接超时时间5s
.setConnectionRequestTimeout(5000) // 设置请求超时时间
.setSocketTimeout(5000)
.setRedirectsEnabled(true)//默认允许自动重定向
.build();
HttpGet httpGet = new HttpGet("http://www.baidu.com");
httpGet.setConfig(requestConfig);
String srtResult = "";
try {
HttpResponse httpResponse = httpClient.execute(httpGet);//执行
if(httpResponse.getStatusLine().getStatusCode() == 200){//执行成功
srtResult = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");//获得返回的结果
System.out.println(srtResult);
}else
{
//异常处理
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
public class HttpComponentsPostTest {
public final static void main(String[] args) throws Exception {
//获取可关闭的 httpCilent
//CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpClient httpClient = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();
//配置超时时间
RequestConfig requestConfig = RequestConfig.custom().
setConnectTimeout(10000).setConnectionRequestTimeout(10000)
.setSocketTimeout(10000).setRedirectsEnabled(false).build();
HttpPost httpPost = new HttpPost("https://tools.usps.com/go/ZipLookupAction.action");
//设置超时时间
httpPost.setConfig(requestConfig);
//装配post请求参数
List<BasicNameValuePair> list = new ArrayList<BasicNameValuePair>();
list.add(new BasicNameValuePair("tAddress", URLEncoder.encode("1 Market Street", "UTF-8"))); //请求参数
list.add(new BasicNameValuePair("tCity", URLEncoder.encode("San Francisco", "UTF-8"))); //请求参数
list.add(new BasicNameValuePair("sState", "CA")); //请求参数
try {
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list,"UTF-8");
//设置post求情参数
httpPost.setEntity(entity);
httpPost.setHeader("User-Agent", "HTTPie/0.9.2");
//httpPost.setHeader("Content-Type","application/form-data");
HttpResponse httpResponse = httpClient.execute(httpPost);
String strResult = "";
if(httpResponse != null){
System.out.println(httpResponse.getStatusLine().getStatusCode());
if (httpResponse.getStatusLine().getStatusCode() == 200) {
strResult = EntityUtils.toString(httpResponse.getEntity());
}
else {
strResult = "Error Response: " + httpResponse.getStatusLine().toString();
}
}else{
}
System.out.println(strResult);
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(httpClient != null){
httpClient.close(); //释放资源
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
参考中国大学mooc《java核心技术》