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");]