1、客戶端與伺服器之間的通訊模型
基於Socket連線的客戶端與伺服器之間的通訊模型圖如上圖所示,整個通訊過程如下所示:
(1) 伺服器端首先啟動監聽程式,對指定的埠進行監聽,等待接收客戶端的連線請求;
(2)客戶端程式啟動,請求連線伺服器的指定埠;
(3)伺服器收到客戶端的連線請求後與客戶端建立套接字(Socket)連線;
(4)連線成功後,客戶端與伺服器分別開啟兩個流,其中客戶端的輸入流連線到伺服器端的輸出流,伺服器的輸入流連線到客戶端的輸出流,兩邊的流連線成功後就可以進行雙向通訊了。
(5)當通訊完畢後,客戶端與伺服器端兩邊各自斷開連線。
注: 套接字(Socket):是一種相互通訊計算機之間的雙向埠,具體包括主機的IP地址,服務型別,TCP/IP協議的埠。其中,TCP/IP協議的埠就是描述網路通訊傳送和接收的程式的標識資訊,具體說就是為資訊的傳說提供地點。當應用程式與埠繫結後,作業系統將收到的資料傳送到埠指定的應用程式程式。每個埠有一個埠號的識別符號,用來區分不同的埠。埠號可以是0~65535之間的任何數字。
0~255的埠號為系統的保留埠,用於系統程式的通訊;
其他的埠是自由埠,可以為程式自由使用;
已定義的埠號:Tomcat 伺服器的預設通訊埠是8080;
MYSQL預設的通訊埠是3306;
SQLSERVER的預設通訊埠是1433;
2、瀏覽器與伺服器之(B/S)之間的通訊模型
由以上1,可以看出C/S的通訊模式是使用Socket來實現的,而B/S的通訊模式是使用使用http來實現的。http(Hypertext transfer protocol)超文字傳輸協議,是一種詳細規定了瀏覽器與全球資訊網伺服器之間相互通訊的規則。
瀏覽器與伺服器之間的通訊,是一次完整的http通訊過程,包括以下7個步驟:
(1) 建立TCP連線;
(2)瀏覽器向伺服器傳送請求命令(即http請求);
(3)瀏覽器傳送請求頭資訊;
(4)伺服器應答(即http響應);
(5)伺服器傳送應答頭資訊
(6)伺服器向瀏覽器傳送資料
(7)伺服器關閉TCP連線
注: http請求與響應格式,見網址:http://www.cnblogs.com/sntetwt.html
http響應碼(即當我們瀏覽一個網頁時,有時會出現”Not Fonud Error 505"型別的資訊),如下所示:
1×× ——資訊類(Information):表示收到瀏覽器的請求,正在進一步處理;
2×× ——成功類(successful):表示使用者請求被正確接收,理解和處理;
3××——重定向類(Redirection):表示請求沒有成功,客戶必須採取進一步的動作;
4××——客戶端錯誤(Client Error):表示客戶端提交的請求有錯;
5××——伺服器錯誤(Server Error):表示伺服器不能完成對請求的處理。
_____________________Asp.net中C#使用Socket傳送和接收TCP資料示例______________________
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace ConsoleApplication1
{
public static class SocketTest
{
private static Encoding encode = Encoding.Default;
/// <summary>
/// 監聽請求
/// </summary>
/// <param name="port"></param>
public static void Listen(int port)
{
Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(new IPEndPoint(IPAddress.Any, port));
listenSocket.Listen(100);
Console.WriteLine("Listen " + port + " ...");
while (true)
{
Socket acceptSocket = listenSocket.Accept();
string receiveData = Receive(acceptSocket, 5000); //5 seconds timeout.
Console.WriteLine("Receive:" + receiveData);
acceptSocket.Send(encode.GetBytes("ok"));
DestroySocket(acceptSocket); //import
}
}
/// <summary>
/// 傳送資料
/// </summary>
/// <param name="host"></param>
/// <param name="port"></param>
/// <param name="data"></param>
/// <returns></returns>
public static string Send(string host, int port, string data)
{
string result = string.Empty;
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect(host, port);
clientSocket.Send(encode.GetBytes(data));
Console.WriteLine("Send:" + data);
result = Receive(clientSocket, 5000 * 2); //5*2 seconds timeout.
Console.WriteLine("Receive:" + result);
DestroySocket(clientSocket);
return result;
}
/// <summary>
/// 接收資料
/// </summary>
/// <param name="socket"></param>
/// <param name="timeout"></param>
/// <returns></returns>
private static string Receive(Socket socket, int timeout)
{
string result = string.Empty;
socket.ReceiveTimeout = timeout;
List<byte> data = new List<byte>();
byte[] buffer = new byte[1024];
int length = 0;
try
{
while ((length = socket.Receive(buffer)) > 0)
{
for (int j = 0; j < length; j++)
{
data.Add(buffer[j]);
}
if (length < buffer.Length)
{
break;
}
}
}
catch { }
if (data.Count > 0)
{
result = encode.GetString(data.ToArray(), 0, data.Count);
}
return result;
}
/// <summary>
/// 銷燬Socket物件
/// </summary>
/// <param name="socket"></param>
private static void DestroySocket(Socket socket)
{
if (socket.Connected)
{
socket.Shutdown(SocketShutdown.Both);
}
socket.Close();
}
}
}
傳送和接收TCP資料:
SocketTest.Send("127.0.0.1", 8888, "www.111cn.net");]