`
hududanyzd
  • 浏览: 815686 次
文章分类
社区版块
存档分类
最新评论

C#中Socket服务端代码分享

 
阅读更多

最近在对项目中Socket通讯中的服务端代码进行优化,保证能接受尽可能多的客户端的连接,并且不会丢掉连接,不会掉数据包。经过一段时间的反复测试和修改,终于达到了这一要求。服务端代码采用了异步通讯的方式,并使用ManualResetEvent来对线程进行控制。在程序中,ManualResetEvent 的使用很关键。 ManualResetEvent 允许线程通过发信号互相通信。通常,此通信涉及一个线程在其他线程进行之前必须完成的任务。当一个线程开始一个活动(此活动必须完成后,其他线程才能开始)时,它调用 Reset 以将 ManualResetEvent 置于非终止状态,此线程可被视为控制 ManualResetEvent。调用 ManualResetEvent 上的 WaitOne 的线程将阻止,并等待信号。当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。一旦它被终止,ManualResetEvent 将保持终止状态(即对 WaitOne 的调用的线程将立即返回,并不阻塞),直到它被手动重置。可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态,如果初始状态处于终止状态,为 true;否则为 false。现在贴出主要的代码,欢迎大家指正,代码如下所示:

void ButtonStartListenClick(object sender, System.EventArgs e)
{
try
{
// Check the port value
if(textBoxPort.Text == "")
{
MessageBox.Show("Please enter a Port Number");
return;
}
if (txtConnectNum.Text.Trim() != "")
{
iConnectNum = int.Parse(txtConnectNum.Text.Trim());
Flage = 0;
}
else
{
MessageBox.Show("Please enter a Connect Number");
return;
}

string portStr = textBoxPort.Text;
int port = System.Convert.ToInt32(portStr);
// Create the listening socket...
m_mainSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
IPEndPoint ipLocal = new IPEndPoint (IPAddress.Any, port);
// Bind to local IP Address...
m_mainSocket.Bind( ipLocal );
// Start listening...
m_mainSocket.Listen(10000);
// Set the event to nonsignaled state.设置无信号状态的事件
allDone.Reset();
// Create the call back for any client connections...
m_mainSocket.BeginAccept(new AsyncCallback (OnClientConnect), null);
// Wait until a connection is made before continuing.等待连接创建后继续
allDone.WaitOne();

UpdateControls(true);

}
catch(SocketException se)
{
MessageBox.Show ( se.Message );
}

}


// This is the call back function, which will be invoked when a client is connected
public void OnClientConnect(IAsyncResult asyn)
{
try
{
//让它继续处理并建立与客户端的连接
allDone.Set();

// Here we complete/end the BeginAccept() asynchronous call
// by calling EndAccept() - which returns the reference to
// a new Socket object
Socket workerSocket = m_mainSocket.EndAccept (asyn);

// Now increment the client count for this client
// in a thread safe manner
Interlocked.Increment(ref m_clientCount);

if (m_clientCount == 1)
{
lock (this)
{
stopwatch.Start();
dtStart = DateTime.Now;
writeLog("Server Start Socket Connect Time"+dtStart.ToString("yyyy-MM-dd HH:mm:ss fff"));
}
}

// Add the workerSocket reference to our ArrayList
m_workerSocketList.Add(workerSocket);

// Send a welcome message to client
string msg = "Welcome client " + m_clientCount + "\n";
SendMsgToClient(msg, m_clientCount);

// Update the list box showing the list of clients (thread safe call)
UpdateClientListControl();

// Let the worker Socket do the further processing for the
// just connected client
WaitForData(workerSocket, m_clientCount);

// Since the main Socket is now free, it can go back and wait for
// other clients who are attempting to connect
m_mainSocket.BeginAccept(new AsyncCallback ( OnClientConnect ),null);
// Wait until a connection is made before continuing.等待连接创建后继续
allDone.WaitOne();
}
catch(ObjectDisposedException)
{
System.Diagnostics.Debugger.Log(0,"1","\n OnClientConnection: Socket has been closed\n");
}
catch(SocketException se)
{
MessageBox.Show ( se.Message );
}

}


public class SocketPacket
{
// Constructor which takes a Socket and a client number
public SocketPacket(System.Net.Sockets.Socket socket, int clientNumber)
{
m_currentSocket = socket;
m_clientNumber = clientNumber;
}
public System.Net.Sockets.Socket m_currentSocket;
public int m_clientNumber;
// Buffer to store the data sent by the client
public byte[] dataBuffer = new byte[1024];
}
// Start waiting for data from the client
public void WaitForData(System.Net.Sockets.Socket soc, int clientNumber)
{
try
{
if ( pfnWorkerCallBack == null )
{
// Specify the call back function which is to be
// invoked when there is any write activity by the
// connected client
pfnWorkerCallBack = new AsyncCallback (OnDataReceived);
}
SocketPacket theSocPkt = new SocketPacket (soc, clientNumber);
//receiveDone.Reset();
soc.BeginReceive (theSocPkt.dataBuffer, 0,
theSocPkt.dataBuffer.Length,
SocketFlags.None,
pfnWorkerCallBack,
theSocPkt);
//receiveDone.WaitOne();
}
catch(SocketException se)
{
MessageBox.Show (se.Message );
}
}
// This the call back function which will be invoked when the socket
// detects any client writing of data on the stream
public void OnDataReceived(IAsyncResult asyn)
{
SocketPacket socketData = (SocketPacket)asyn.AsyncState ;
try
{
// Complete the BeginReceive() asynchronous call by EndReceive() method
// which will return the number of characters written to the stream
// by the client
//receiveDone.Set();
int iRx = socketData.m_currentSocket.EndReceive (asyn);
char[] chars = new char[iRx + 1];
// Extract the characters as a buffer
System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
int charLen = d.GetChars(socketData.dataBuffer,
0, iRx, chars, 0);

System.String szData = new System.String(chars);
string msg = "" + socketData.m_clientNumber + ":";
AppendToRichEditControl(msg + szData);
//writeFromClientsMsgLog(msg + szData);

// Send back the reply to the client
string replyMsg = "Server Reply:" + szData.ToUpper();
// Convert the reply to byte array
byte[] byData = System.Text.Encoding.ASCII.GetBytes(replyMsg);

Socket workerSocket = (Socket)socketData.m_currentSocket;
workerSocket.Send(byData);


if (m_clientCount == iConnectNum && Flage == 0)
{
Interlocked.Increment(ref Flage);
string msgTime = "Server End Socket Action Time:";
lock(this)
{
stopwatch.Stop();
//lblTime.Text = stopwatch.Elapsed.Seconds.ToString();
int itime = stopwatch.Elapsed.Milliseconds;

//msgTime += stopwatch.Elapsed.Seconds.ToString()+"--"+itime.ToString();
msgTime += DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff");
}
writeLog(msgTime);

writeClientConnectionLog();

//UpdateLabelTime(msgTime);
//byData = System.Text.Encoding.ASCII.GetBytes(msgTime);
//workerSocket.Send(byData);
}

// Continue the waiting for data on the Socket
WaitForData(socketData.m_currentSocket, socketData.m_clientNumber );

}
catch (ObjectDisposedException )
{
System.Diagnostics.Debugger.Log(0,"1","\nOnDataReceived: Socket has been closed\n");
}
catch(SocketException se)
{
if(se.ErrorCode == 10054) // Error code for Connection reset by peer
{
string msg = "Client " + socketData.m_clientNumber + " Disconnected" + "\n";
AppendToRichEditControl(msg);
//writeFromClientsMsgLog(msg);

// Remove the reference to the worker socket of the closed client
// so that this object will get garbage collected
m_workerSocketList[socketData.m_clientNumber - 1] = null;
UpdateClientListControl();
}
else
{
MessageBox.Show (se.Message );
}
}
}


void CloseSockets()
{
if(m_mainSocket != null)
{
m_mainSocket.Close();
}
Socket workerSocket = null;
for(int i = 0; i < m_workerSocketList.Count; i++)
{
workerSocket = (Socket)m_workerSocketList[i];
if(workerSocket != null)
{
workerSocket.Close();
workerSocket = null;
}
}
}

void SendMsgToClient(string msg, int clientNumber)
{
// Convert the reply to byte array
byte[] byData = System.Text.Encoding.ASCII.GetBytes(msg);

Socket workerSocket = (Socket)m_workerSocketList[clientNumber - 1];
//workerSocket.Send(byData);
workerSocket.BeginSend(byData, 0, byData.Length, 0,
new AsyncCallback(SendCallback), workerSocket);
}

private void SendCallback(IAsyncResult asyn)
{
Socket client = (Socket)asyn.AsyncState;
// 完成数据发送.
int bytesSent = client.EndSend(asyn);
}

完整的代码可以在我的资源中下载到,资源的名称为C#中Socket服务端通讯的代码


分享到:
评论

相关推荐

    C#中Socket服务端通讯的代码

    本篇文章将详细解析标题中的"C#中Socket服务端通讯的代码",以及如何实现高效、稳定的服务端通讯。 Socket在计算机网络中扮演着数据传输的基础角色,它允许应用程序通过网络发送和接收数据。在C#中,Socket类位于...

    TCP socket服务端代码 C#

    在IT行业中,网络通信是不可或缺的...通过学习和理解这段C# TCP socket服务端代码,开发者可以构建自己的网络服务,用于GPRS环境中的数据交互。同时,掌握这些技术对于开发基于移动网络的IoT(物联网)应用也非常重要。

    C#SuperSocket服务端与客户端通信实例

    在提供的压缩包文件"SuperSocket"中,你应该能找到更详细的示例代码和文档,帮助你进一步理解和实践SuperSocket在C#中的使用。通过深入学习和实践,你可以掌握基于SuperSocket的网络通信技术,这对于开发复杂的网络...

    C# Socket 客户端服务端封装带使用实例

    Socket编程在IT行业中是网络通信的基础,特别是在C#这样的编程语言中,Socket接口提供了与TCP/IP协议栈直接交互的能力。本篇文章将详细讲解C#中Socket客户端和服务端的封装,以及如何利用队列处理和实际应用示例。 ...

    socket通信服务端C#代码

    本文将深入探讨如何使用C#语言来编写一个简单的Socket服务端程序。标题中的"socket通信服务端C#代码"提示我们将重点研究C#中的Socket类以及如何构建一个基本的服务器端应用。 首先,C#中的System.Net.Sockets命名...

    c# tcpsocket 原生代码编写 客户端和服务端程序

    本教程将深入探讨如何使用C#语言编写原生的TCP Socket客户端和服务端程序。TCP是一种面向连接的、可靠的传输协议,而Socket是TCP/IP协议族中用于进程间通信的接口。下面我们将详细讲解这两个方面的知识。 首先,...

    C# socket通讯服务端

    在实际开发中,C# Socket服务端还需要考虑以下关键点: - **并发处理**:当多个客户端同时连接时,服务端必须能够有效地管理这些连接,避免阻塞和资源浪费。多线程或异步编程模型可以用来实现并发。 - **错误处理...

    C# winform做的网络通讯Socket服务端(附原码)

    在本文中,我们将深入探讨如何使用C#编程语言构建一个基于WinForm的网络通信Socket服务端。这个服务端设计用于接收客户端发送的SQL语句,处理这些语句,并将结果以DATATABLE的形式回传。首先,让我们了解Socket通信...

    C# Socket 客户端服务端封装 支持多连接处理 Tasks多线程 队列处理 大数据拆分包处理

    在Socket服务端,每个新连接可以被封装为一个Task,从而实现并发处理,提高服务性能。 5. **队列处理**: - 当并发连接数量过大时,使用队列可以避免过多的并发操作导致的资源竞争。客户端请求被放入队列,按顺序...

    C# Socket_服务端向指定的客户端发送消息(包含服务器)

    在本文中,我们将深入探讨如何使用C#的Socket编程来实现一个简单的聊天应用程序,其中包含服务器和客户端的交互。Socket编程是网络通信的基础,它允许应用程序通过网络进行数据传输。在C#中,System.Net命名空间下的...

    C# Socket聊天服务端程序

    创建Socket服务端的第一步是实例化一个Socket对象,并指定其使用的协议类型。在TCP/IP环境中,通常选择StreamSocket或TcpListener。这里我们使用TcpListener,它专门用于监听TCP连接请求。创建TcpListener时,需要...

    c#异步socket服务端客户端

    C#异步Socket编程是网络通信领域中的一个重要概念,它允许开发者在不阻塞主线程的情况下处理网络数据传输。在C#中,Socket类提供了异步操作的能力,这对于构建高性能、高并发的服务器和客户端应用至关重要。下面我们...

    C#Socket服务端与客户端

    C#Socket服务端与客户端

    C#聊天程序服务端源代码

    通过分析源代码,我们可以更好地理解Socket通信机制,并学习如何在C#中进行网络编程。 #### 二、关键知识点详解 ##### 1. Socket编程基础 Socket编程是网络编程的基础之一,它提供了不同主机之间进行通信的能力。...

    C#版Socket通信含服务端、客户端、WebSocket,代码完整清晰

    Socket通信在IT行业中是网络编程的基础,特别是在C#开发中,它被广泛用于构建服务器和客户端应用程序,实现数据的高效传输。本项目包含了一个完整的C#版Socket通信示例,涵盖了服务端、客户端以及WebSocket的实现,...

    稳定可靠的C# 高性能Socket网络服务端和客户端组件

    稳定可靠的C# IOCP组件,加入底层心跳检测机制,支持批量发送多个数据包。...网络异常断线(服务端运行于虚拟机,然后禁用虚拟机网卡),超过心跳检测时间,能够自动关闭Socket. 客户端可作为服务器压力测试工具。

    C#编写Socket服务器源码

    基于C#语言开发,根据Sockect通信原理和Scoket通信流程编写的案例程序,每一步都有详细注解,根据需要修改就可以应用。

    C# socket 服务端与客户端通信演示代码

    在本文中,我们将深入探讨C#中的套接字(socket)编程,特别是在服务端与客户端之间的通信。套接字是网络编程的基础,它允许不同计算机上的应用程序之间进行数据交换。C#提供了System.Net.Sockets命名空间,其中包含...

    C#Socket服务端.zip

    在“C# Socket服务端.zip”这个压缩包中,可能包含了以下内容: - 示例代码:展示如何创建、初始化Socket,绑定端口,开始监听,接受连接,以及处理数据传输的C#源代码。 - 说明文档:可能包含详细的步骤解释,以及...

    C# Socket通讯/TCP通讯,完整代码demo

    在C#的SocketDemo中,你可能看到以下关键代码片段: ```csharp // 创建Socket对象 Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // 绑定到本地IP和端口 ...

Global site tag (gtag.js) - Google Analytics