C#socket通信(客户端和服务端)
注意:此例子的目的只是为了说明用套接字写程序的大概思路,而不是实际项目中的使用程序。在这个例子中,实际上还有很多问题没有解决,如消息边界问题、端口号是否被占用、消息命令的解析、粘包、断包问题等。。
源码下载地址
http://download.csdn.net/detail/pplsunny/9663876
TCP/IP:Transmission Control Protocol/Internet Protocol,传输控制协议/因特网互联协议,又名网络通讯协议。简单来说:TCP控制传输数据,负责发现传输的问题,一旦有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地,而IP是负责给因特网中的每一台电脑定义一个地址,以便传输。从协议分层模型方面来讲:TCP/IP由:网络接口层(链路层)、网络层、传输层、应用层。它和OSI的七层结构以及对于协议族不同,下图简单表示:
现阶段socket通信使用TCP、UDP协议,相对应UDP来说,TCP则是比较安全稳定的协议了。本文只涉及到TCP协议来说socket通信。首先讲述TCP/IP的三次握手,在握手基础上延伸socket通信的基本过程。
下面介绍对于应届生毕业面试来说是非常熟悉的,同时也是最臭名昭著的三次握手:
1 客户端发送syn报文到服务器端,并置发送序号为x。
2 服务器端接收到客户端发送的请求报文,然后向客户端发送syn报文,并且发送确认序号x+1,并置发送序号为y。
3 客户端受到服务器发送确认报文后,发送确认信号y+1,并置发送序号为z。至此客户端和服务器端建立连接。
在此基础上,socket连接过程:
服务器监听:服务器端socket并不定位具体的客户端socket,而是处于等待监听状态,实时监控网络状态。
客户端请求:客户端clientSocket发送连接请求,目标是服务器的serverSocket。为此,clientSocket必须知道serverSocket的地址和端口号,进行扫描发出连接请求。
连接确认:当服务器socket监听到或者是受到客户端socket的连接请求时,服务器就响应客户端的请求,建议一个新的socket,把服务器socket发送给客户端,一旦客户端确认连接,则连接建立。
注:在连接确认阶段:服务器socket即使在和一个客户端socket建立连接后,还在处于监听状态,仍然可以接收到其他客户端的连接请求,这也是一对多产生的原因。
下图简单说明连接过程:
socket连接原理知道了,此处编写最基本最简单的socket通信:
服务器端:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
namespace WFSocket
{
public partial class Form1 : Form
{
/// <summary>
/// 用来存放连接服务的客户端的IP地址和端口号,对应的Socket
/// </summary>
Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();
//
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 初期化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Form1_Load(object sender, EventArgs e)
{
//不检测跨线程之间的空间调用
Control.CheckForIllegalCrossThreadCalls = false;
//获取本地IP地址
ipAddress.Text = GetAddressIP();
}
/// <summary>
/// 开始监听按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnListen_Click(object sender, EventArgs e)
{
try
{
//当点击开始监听的时候 在服务器端创建一个负责监IP地址跟端口号的Socket
Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//获取IP
//IPAddress ip = IPAddress.Any;
//服务器IP地址
bool isIp= IPCheck(ipAddress.Text.Trim());
if (!isIp) {
ShowMsg("IPアドレスエラー");
return;
}
IPAddress ip = IPAddress.Parse(ipAddress.Text.Trim());
//创建端口号
string strPort=serverPort.Text.Trim();
bool isNum = CheckNumber(strPort);
if (isNum)