1,網絡通訊中的三個要素
IP地址
網絡中設備的標識
不宜記憶,可用主機名
本地迴環地址:127.0.0.1主機名:localhost
端口號
用於標識進程的邏輯地址,不同進程的標識
有效端口:0-65535,其中,0-1024系統使用或者保留端口子
傳輸協議
通訊規則
常見協議:TCP,UDP
2,IP簡述使用:
import java.net.InetAddress;
import java.net.UnknownHostException;
public class Test1 {
public static void main(String[] args) {
try {
//本地主機ip地址對象
InetAddress ip=InetAddress.getLocalHost();
//獲取其他主機ip地址對象
ip=InetAddress.getByName("192.168.100");
System.out.println(ip.getHostAddress());//地址
System.out.println(ip.getHostName());//主機名
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3,UDP,TCP,Socket
UDP
將數據及源和目的封裝成數據包中,不需要建立連接
每個數據包的大小限制在64k內
因爲無連接,是不可靠協議
不需要建立連接,速度快
TCP
建立連接,形成傳輸數據的通道
在連接中進行大數據傳輸
通過三次握手完成連接,是可靠協議
必須建立連接,效率會稍低
Socket
就是爲網絡服務提供一種機制
通信的兩端都有Socket。//只要有了它,才能進行連接,連接後纔有通路,現有碼頭,再有船
網絡通信其實就是Socket間的通信
數據在兩個Socket間通過IO傳輸
理解:港口,插座,應用程序通信,Socket有了,但是傳輸協議不一樣,每個傳輸協議都有自己的建立端點的方式,udp,tcp
4,兩個類
DatagramSocket
DatagramPacket
5,UDP建立發送端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
/*
* 需求:通過udp傳輸方式,將一段文字數據發送出去
* 1,建立udpSocket服務
* 2,提供數據,並將數據封裝到數據包中。
* 3,通過socket服務的發送功能,將數據發出去
* 4,關閉資源
*/
public class UdpSend {
public static void main(String[] args) {
try {
// 創建udp服務通過DatagramSocket對象
DatagramSocket ds = new DatagramSocket(8888);//可以不指定,系統隨機分配
// 確定數據,將數據封裝成包
byte[] b = "aaa".getBytes();
try {
DatagramPacket dp = new DatagramPacket(b, b.length, InetAddress
.getByName("192.168.1.100"), 10000);
ds.send(dp);// 通過socket服務發送數據包
ds.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
6,udp建立接受端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.Scanner;
/*
* 需求:
* 定義一個應用程序,用於接收ydp協議傳輸的數據並處理的
* 思路
* 1,定義udpsocket服務.通常會監聽一個端口,其實就是給這個接收網絡應用程序定義數字標識
* 方便於明確,那些數據過來,該應用程序可以處理
* 2,定義一個數據包,因爲要存儲接收到的字節數據。
* 因爲數據包對象中有更多功能可以提取字節數據中的不同數據信息
* 3,通過socket服務receive方法將收到的數據存入已定義好的數據包。
* 4,通過數據包對象的特有功能。講這些不同的數據取出,打印在控制檯上。
* 5,關閉資源
*
*/
public class UdpRe {
public static void main(String[] args) {
DatagramSocket ds = null;
try {
// 1建立udp socket,建立端點
ds = new DatagramSocket(1000);// 系統可以分配
// 2定義數據包,
byte[] b = new byte[1024];
DatagramPacket dp = new DatagramPacket(b, b.length);
// 3通過服務的receive方法將收到的數據存入數據包中。
ds.receive(dp);//阻塞式方法,沒有數據就等,線程機制wait,發過來數據的時候notify喚醒
// 4,通過數據包的方法獲取其中的數據
String ip = dp.getAddress().getHostAddress();
String data = new String(dp.getData(), 0, b.length);
int post = dp.getPort();
System.out.println(ip + "::" + data + "::" + post);
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
ds.close();
}
}
}
7 ,udp簡單聊天程序
/*
* 聊天程序
* 有接受數據的部分和發數據的部分
* 並且同時執行
* 多線程技術
* 因爲收數據和發數據是不一致的,所有要定義兩個run方法,所以要有兩個類
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
public class Test9 {
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
DatagramSocket sendsocket = new DatagramSocket();//發送端
DatagramSocket recesocket = new DatagramSocket(10001);//接受端必須制定端口號
Thread t1 = new Thread(new Send(sendsocket));//發送端線程
Thread t2 = new Thread(new Rece(recesocket));//接收端 線程
t1.start();
t2.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/*
* 發送端類
*
* @author Administrator
*/
class Send implements Runnable {
private DatagramSocket ds;//udpsocket服務
public Send(DatagramSocket ds) {// 初始化一個發送端DatagramSocket對象
this.ds = ds;
}
//重寫run方法,鍵盤錄入io操作
public void run() {
// TODO Auto-generated method stub
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));// 鍵盤錄入
try {
String line = null;
while ((line = br.readLine()) != null) {// 循環讀取
if (line.equals("86"))//自定義結束標記
break;
// 構造數據包,封裝了數據,接受ip,接受端口,存儲數據
byte[] b = line.getBytes();
DatagramPacket dp = new DatagramPacket(b, b.length, InetAddress
.getByName("192.168.1.100"), 10001);//封裝數據包
ds.send(dp);//發送
}
} catch (Exception e) {
// TODO Auto-generated catch block
try {
throw new Exception("發送端失敗");
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
} finally {
ds.close();//關閉資源
}
}
}
/*
* 接收 發送端類
*
* @author Administrator
*/
class Rece implements Runnable {
private DatagramSocket ds;
public Rece(DatagramSocket ds) {// 初始化一個接受端DatagramSocket對象,接受數據 必須明確一個端口號
this.ds = ds;
}
@Override
public void run() {// 重寫線程run方法
// TODO Auto-generated method stub
while (true) {
byte[] b = new byte[1024];
DatagramPacket dp = new DatagramPacket(b, b.length);//創建數據包,用於存儲接受的數據
try {
ds.receive(dp);// 阻塞式方法,將接受的數據存儲到數據包中
// 通過數據包獲取ip,和轉換後的字符串
String ip = dp.getAddress().getHostName();//通過數據包的方法解析包中的數據
String data = new String(dp.getData(), 0, dp.getLength());
System.out.println("ip" + ip + "data" + data);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
8,TCP傳輸
Socket(客戶端對象)和ServerSocket(服務端對象)
建立客戶端和服務端
建立連接後,通過Socket中的io流進行數據的傳輸
關閉Socket
同樣,客戶端與服務器端是兩個獨立的應用程序
客戶端一建立,就要連接服務端
9,TCP建立客戶端
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/*
* 客戶端
* 通過查閱socket對象,發現在該對象建立時,就可以去連接指定主機
* 因爲tcp是面向連接的,所以在建立連接socket服務時。
* 就要有服務端存在,並連接成功。形成通路後,在該通道進行數據的傳輸。
* 需求;給服務端發送一個文本數據
* 步驟
*
* 1,創建TCP 客戶端Socket服務,使用Socket對象。並指定要連接的主機和端口
* 建議該對象一創建就明確目的地。要連接主機
* 2,如果連接成功,說明數據的通道已建立
* 該通道是Socket流,是底層的,既然是流,說明這裏既有輸入又有輸出
* 可以通過getOutputStream(),和getInputSteam()來獲取兩個字節流
* 3,使用輸出流。將數據寫出
* 4,關閉資源
*/
public class TcpClient {
public static void main(String[] args) {
try {
// 創建客戶端的socket服務,指定目的主機和端口
Socket s = new Socket("192.168.1.100", 10001);
// 爲了發送數據,應該獲取socket流中的輸出流
OutputStream out = s.getOutputStream();
out.write("aaa".getBytes());
s.close();// socket關閉,流也關閉了
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
10 ,使用TCP建立服務端
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public static void main(String[] args) {
Socket s = null;
ServerSocket ss = null;
try {
// 建立服務端的socket,並監聽一個端口
ss = new ServerSocket(10001);
// 通過accept方法獲取連接過來的客戶端對象
s = ss.accept();// 阻塞式的方法
String ip = s.getInetAddress().getHostAddress();
System.out.println("ip:" + ip);
// 獲取客戶端發送過來的數據,那麼要使用客戶端對象的讀取流方法來讀取數據
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
System.out.println(new String(buf, 0, buf.length));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
s.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}// 不關自己,關閉客戶端
try {
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
11,使用tcp建立交互方式
客戶端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
/*
* 客服端
* 1,建立socket服務指定要連接主機和端口子
* 2,獲取socket流中的輸出流,將數據寫到該流中,通過網絡發送給服務端
*
*/
public class TcpClient {
public static void main(String[] args) {
try {
Socket s = new Socket("192.168.1.240", 10002);
OutputStream out = s.getOutputStream();
out.write("服務端,你好".getBytes());
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read();
System.out.println(new String(buf, 0, len));
s.close();
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
服務端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class TcpServer {
public static void main(String[] args) {
// 服務端接受客戶端發送過來的數據,並打印在控制檯上
/*
* 通過tcp服務的思路 1,建立服務端socket服務。通過ServerSocket對象 2,服務端必須對外提供一個藉口,否則客戶端無法連接
* 3,獲取鏈接過來的客戶端對象 4,通過客戶端對象獲取socket流讀取客戶端發來的數據 並打印在控制檯上 5,關閉資源,管客戶端,管服務端
*/
try {
// 1創建服務端對象
ServerSocket ss = new ServerSocket(10002);
// 獲取連接過來的客戶端對象
Socket s = ss.accept();
// 2獲取ip
String ip = s.getInetAddress().getHostAddress();
System.out.println("ip:" + ip);
// 通過socket對象獲取輸入流,要對客戶端發過來的數據
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
System.out.println(new String(buf, 0, len));
// 使用客戶端socket對象的輸出流給客戶端返回數據
OutputStream out = s.getOutputStream();
out.write("收到".getBytes());
s.close();
ss.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
客戶端上傳圖片
單人
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
/*
* 單人上傳圖片
* 客戶端。
* 1,服務端點
* 2,去讀客戶端已有的圖片數據
* 3,通過socket輸出流將數據發送給服務端
* 4,讀取服務端反饋信息
* 5,關閉
*/
public class PicClient {
public static void main(String[] args) throws Exception, IOException {
Socket s = new Socket("192.168.1.100", 10004);
FileInputStream fis = new FileInputStream("c:\\1.jpg");
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {
out.write(buf, 0, len);
}
// 告訴服務端數據已寫完
s.shutdownOutput();
InputStream in = s.getInputStream();
byte[] bufin = new byte[1024];
int num = in.read(bufin);
System.out.println(new String(bufin, 0, num));
fis.close();
s.close();
}
}
class PicServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10004);
Socket s = ss.accept();
InputStream in = s.getInputStream();
FileOutputStream fos = new FileOutputStream("c:\\server.jpg");
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf)) != -1) {
fos.write(buf, 0, len);
}
OutputStream out = s.getOutputStream();
out.write("上傳成功".getBytes());
fos.close();
s.close();
ss.close();
}
}
客戶端併發上傳圖片
加上while的方案
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
/*
* 單人上傳圖片
* 客戶端。
* 1,服務端點
* 2,去讀客戶端已有的圖片數據
* 3,通過socket輸出流將數據發送給服務端
* 4,讀取服務端反饋信息
* 5,關閉
*/
public class PicClient {
public static void main(String[] args) throws Exception, IOException {
Socket s = new Socket("192.168.1.100", 10004);
FileInputStream fis = new FileInputStream("c:\\1.jpg");
OutputStream out = s.getOutputStream();
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {
out.write(buf, 0, len);
}
// 告訴服務端數據已寫完
s.shutdownOutput();
InputStream in = s.getInputStream();
byte[] bufin = new byte[1024];
int num = in.read(bufin);
System.out.println(new String(bufin, 0, num));
fis.close();
s.close();
}
}
class PicServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10004);
while(true){
Socket s = ss.accept();
InputStream in = s.getInputStream();
FileOutputStream fos = new FileOutputStream("c:\\server.jpg");
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf)) != -1) {
fos.write(buf, 0, len);
}
OutputStream out = s.getOutputStream();
out.write("上傳成功".getBytes());
fos.close();
s.close();
ss.close();
}
}
}
這個服務端有個侷限性。當a客戶端連接上以後,被服務端獲取到,服務端執行具體執行流程,
這時b客戶端連接,只有等待
因爲服務端還沒有處理完A客戶端的請求,還沒有循環回來執行accept方法。所以暫時獲取不到B客戶對象。
那麼爲了可以讓多個客戶端同時併發訪問服務
那麼服務端最好就是將每個客戶端封裝到一個單獨的線程中。這樣,就可以同屬處理多個客戶端請求。
如何定義線程呢?
只要明確了每一個客戶端要在服務端執行的代碼即可。將該代碼存入run方法中。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
public class PicClient {
public static void main(String[] args) throws Exception, IOException {
// 主函數傳值
if (args.length != 1) {
System.out.println("請選擇一個jpd格式的圖片");
return;
}
File file = new File(args[0]);//根據傳入的值,實例file對象
if (!(file.exists() && file.isFile())) {//判斷是否存在,是不是文件
System.out.println("該文件有問題,要麼不存在,要麼不是文件");
return;
}
if (!(file.getName().endsWith(".jpg"))) {//判斷是不是以.jpg爲後綴的
System.out.println("圖片格式錯誤,請重新選擇");
return;
}
if (file.length() > 1024 * 1024 * 5) {//對文件的大小進行設置
System.out.println("文件過大");
return;
}
Socket s = new Socket("192.168.1.100", 10004);//指定ip和端口號
FileInputStream fis = new FileInputStream("c:\\1.jpg");//得到文件輸入流,根據文件所在的路徑
OutputStream out = s.getOutputStream();//得到輸出流
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {//把文件寫入指定的流中。上傳到客戶端
out.write(buf, 0, len);
}
// 告訴服務端數據已寫完
s.shutdownOutput();
InputStream in = s.getInputStream();//得到服務端的反饋信息
byte[] bufin = new byte[1024];//緩衝數組
int num = in.read(bufin);//讀取的字節數
System.out.println(new String(bufin, 0, num));//打印輸出
fis.close();
s.close();
}
}
class PicServer {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(10004);//服務端Socket指定端口
while (true) {
Socket s = ss.accept();//阻塞式接受
new Thread(new PicThread(s)).start();//線程開啓,多線程,併發上傳
}
}
}
class PicThread implements Runnable {
private Socket s;
PicThread(Socket s) {
this.s = s;
}
@Override
public void run() {
// TODO Auto-generated method stub
int count = 1;// 如果定義到成員,多個線程共享數據了。不安全
String ip = s.getInetAddress().getHostAddress();
try {
System.out.println(ip + "...connected");
InputStream in = s.getInputStream();
// 爲了不覆蓋,用ip地址來命名
File file = new File(ip + "(" + (count) + ")" + ".jpg");
while (file.exists()) {//判斷文件是否存在
file = new File(ip + "(" + (count++) + ")" + ".jpg");
}
FileOutputStream fos = new FileOutputStream(file);//文件輸出流
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf)) != -1) {
fos.write(buf, 0, len);
}
OutputStream out = s.getOutputStream();
out.write("上傳成功".getBytes());//返回給客戶端的信息
fos.close();
s.close();
} catch (Exception e) {
throw new RuntimeException(ip + "上傳失敗");
}
}
}
客戶端併發登陸
客戶端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
/*
*客戶端通過鍵盤錄入用戶名。
*服務端對這個用戶名進行校驗。
*如果該用戶名存在,在服務端系那是xxx,已登錄
*並在客戶端顯示xxx歡迎光臨。
*如果該用戶不存在在服務端顯示xxx,嘗試登陸。
*並在客戶端顯示xxx,該用戶不存在。
*最多就登陸三次
*
*/
public class LoginClient{
public static void main(String[] args) throws Exception, IOException {
Socket s=new Socket("192.168.1.100",10006);
BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
PrintWriter out=new PrintWriter(s.getOutputStream(),true);
BufferedReader bufin=new BufferedReader(new InputStreamReader(s.getInputStream()));
for(int x=0;x<3;x++){
String line=bufr.readLine();//讀一次
if(line==null){
break;
}
out.println(line);//發出去
String info=bufin.readLine();//讀取服務端的反饋信息
System.out.println("info:"+info);//打印反饋信息
if(info.contains("歡迎")){
break;
}
}
bufr.close();
s.close();
}
}
服務端
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class LoinServer {
public static void main(String[] args) throws Exception {
ServerSocket ss=new ServerSocket(10006);
while(true){
Socket s=ss.accept();
new Thread(new UserThread(s)).start();
}
}
}
class UserThread implements Runnable{
private Socket s;
UserThread(Socket s){
this.s=s;
}
@Override
public void run() {
// TODO Auto-generated method stub
String ip=s.getInetAddress().getHostAddress();
System.out.println(ip+"...connected");
try{
for(int x=0;x<3;x++){
BufferedReader bufin=new BufferedReader(new InputStreamReader(s.getInputStream()));
String name=bufin.readLine();
if(name==null){//客戶端ctrl+c停止了
break;
}
BufferedReader bufr=new BufferedReader(new FileReader("c:\\user.txt"));
PrintWriter out=new PrintWriter(s.getOutputStream());
String line=null;
boolean flag=false;
while((line=bufr.readLine())!=null){
if(line.equals(name) ){
flag=true;
break;
}
}
if(flag){
System.out.println(name+",已登錄");
out.println(name+",歡迎光臨");
break;
}else{
System.out.println(name+",嘗試登陸");
out.println(name+",用戶名不存在");
}
}
s.close();
}catch(Exception ex){
throw new RuntimeException(ip+"校驗失敗");
}
}
}
瀏覽器客戶端-自定義服務端
import java.io.IOException;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 演示客戶端和服務端
* 1,客戶端:瀏覽器
* 2,服務端,自定義
*/
public class ServerDemo {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(11000);
Socket s = ss.accept();
System.out.println(s.getInetAddress().getHostAddress());
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
out.println("客戶端你好");
s.close();
ss.close();
}
}
如上圖所示客戶端
瀏覽器客戶端-Tomcat服務端
在tomcat下的webapps下面新建myweb 裏面有一個demo.html文件訪問成功如下圖
自定義瀏覽器-Tomcat服務端
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
/*
*模擬瀏覽器的動作,向tomcat服務請求數據
*瀏覽器在訪問服務器中到底發送了什麼數據?才能請求道myweb資源呢?
*/
public class ServerDemo {
public static void main(String[] args) throws Exception {
ServerSocket ss = new ServerSocket(11000);
Socket s = ss.accept();
System.out.println(s.getInetAddress().getHostAddress());
InputStream in=s.getInputStream();
byte []buf=new byte[1024];
int len=in.read(buf);
System.out.println(new String(buf,0,len));
PrintWriter out = new PrintWriter(s.getOutputStream(), true);
out.println("客戶端你好");
s.close();
ss.close();
}
}
客戶端沒有變化,服務端打印出了一些數據,這些數據到底是什麼呢?
/* 192.168.1.100
GET / HTTP/1.1
Accept: */*
Accept-Language: zh-CN
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; CIBA; .NET4.0C; .NET4.0E; InfoPath.2)
Accept-Encoding: gzip, deflate
Host: 192.168.1.100:11000
Connection: Keep-Alive*/下面還有一行叫做請求數據體
瀏覽器給服務端發送了這些消息,這些就是Http請求消息頭。瀏覽器和tomcat服務器雖然是不同廠商製作的客戶端和服務端,但是他們都遵從了一些國際標準化的協議規則,在底層都走的tcp,在應用層http協議,公共的傳輸規則。瀏覽器廠商要想和不同廠商的服務器進行數據交互的話,他們必須得遵守規則。
自定義客戶端 服務端 tomcat
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
/*
*自定義客戶端
*服務端 tomcat
*
*/
public class MyIE {
public static void main(String[] args) throws Exception, IOException {
Socket s=new Socket("192.168.1.100",8080);
PrintWriter out=new PrintWriter(s.getOutputStream(),true);
out.println("GET /myweb/demo.html HTTP/1.1");
out.println("Accept: */*");//什麼都支持
out.println("Accept-Language: zh-CN");//支持簡體中文
out.println("Connection: Keep-Alive");//加上後變慢。
out.println();//一定要寫空行,要和請求體分開。
out.println(); //一定要寫空行
//服務端要發數據到本瀏覽器中。
BufferedReader bufr=new BufferedReader(new InputStreamReader(s.getInputStream()));
String line=null;
while((line=bufr.readLine())!=null){
System.out.println(line);
}
s.close();
}
}