服务器代码:包含接收、发送、客户端连接状态
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace TCPIP
{
public partial class TCP_Server : Form
{
bool disConnected = false;//客户端断开标志
private Dictionary<string, Socket> clientList = new Dictionary<string, Socket>();/// 创建一个字典,用来存储记录服务器与客户端之间的连接
public TCP_Server()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;///跨线程访问控件
myIPAddress.Text = IPAddress.Any.ToString(); // 获取本地IP
}
private void BegionListen_Click(object sender, EventArgs e)//开始监听
{
Thread myServer = new Thread(MySocket);
myServer.IsBackground = true;//设置这个线程是后台线程
myServer.Start();
BegionListen.Enabled = false;//禁用按钮
}
/// <summary>
/// 创建服务监听
/// </summary>
private void MySocket()
{
//1.创建Socket对象;
Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//
//建立一个EndPoint对象;
IPAddress iP = IPAddress.Parse(myIPAddress.Text);
IPEndPoint endPoint = new IPEndPoint(iP, int.Parse(myServerPort.Text));
//绑定EndPoint;
server.Bind(endPoint);
//开始监听;
//允许同时加入链接的最大数量
server.Listen(20);
listBox_log.Items.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "--服务器已经成功开启!");
//接收到客户端的连接,创建一个新的用于和客户端进行通信的Socket对象;
while (true)
{
//接受接入的一个客户端
Socket connectClient = server.Accept();
if (connectClient != null)
{
string infor = connectClient.RemoteEndPoint.ToString();
clientListShow.Items.Add(infor);
clientList.Add(infor, connectClient);
listBox_log.Items.Add("【系统消息】"+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") +"--"+ infor + "加入服务器!");
///服务器将消息发送至客服端
//string msg = infor + "您已成功接入服务器!";
//SendMsg(msg);
//每有一个客户端接入时,需要有一个线程进行服务
Thread threadClient = new Thread(ReciveMsg);//带参的方法可以把传递的参数放到start中
threadClient.IsBackground = true;
//创建的新的对应的Socket和客户端Socket进行通信
threadClient.Start(connectClient);
}
}
}
/// <summary>
/// 接收到客户端消息处理
/// </summary>
/// <param name="o"></param>
private void ReciveMsg(object o)
{
//Socket connectClient = (Socket)o; //与下面效果一样
Socket connectClient = o as Socket;//connectClient负责客户端的通信
IPEndPoint endPoint = null;
while (true)
{
try
{
///定义服务器接收的字节大小
byte[] arrMsg = new byte[1024 * 1024];
///接收到的信息大小(所占字节数)
int length = 0;//接收数据长度
if (connectClient.Connected)//已连接
{
disConnected = true;
length = connectClient.Receive(arrMsg);
}
else//断开
{
if (disConnected)
{
disConnected = false;
RemoveClient(connectClient.RemoteEndPoint.ToString());
connectClient.Dispose();
//listBox_log.Items.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") +":"+ connectClient.RemoteEndPoint.ToString()+ "断开连接");
}
return;
}
if (length > 0)
{
string recMsg = Encoding.Default.GetString(arrMsg, 0, length);
//获取客户端的端口号
endPoint = connectClient.RemoteEndPoint as IPEndPoint;
//服务器显示客户端的端口号和消息
listBox_log.Items.Add(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "--[" + connectClient.RemoteEndPoint.ToString() + "]:" + recMsg);
RevTxt.Text = recMsg;
//服务器(connectClient)发送接收到的客户端信息给客户端
// SendMsg("[" + endPoint.Port.ToString() + "]:" + recMsg);
}
else
{
if (disConnected)
{
RemoveClient(connectClient.RemoteEndPoint.ToString());
connectClient.Dispose();
disConnected = false;
}
}
}
catch (Exception)
{
///移除添加在字典中的服务器和客户端之间的线程
if (endPoint != null)
{
RemoveClient(endPoint.ToString());
}
connectClient.Dispose();
}
}
}
/// <summary>
/// 删除字典和list显示列表
/// </summary>
/// <param name="clientName"></param>
public void RemoveClient(string clientName)
{
clientList.Remove(clientName);
clientListShow.Items.Remove(clientName);
listBox_log.Items.Add("【系统消息】"+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + "--" + clientName + "已断开连接");
if (clientListShow.Text == clientName) clientListShow.Text = "";//删除显示
}
/// <summary>
/// 服务器向所有客户端发送消息
/// </summary>
/// <param name="str"></param>发送内容
private void SendMsg(string str)
{
///遍历出字典中的所有线程
///
Dictionary<string, Socket> clientListtemp = new Dictionary<string, Socket>();/// 创建一个临时字典
clientListtemp = clientList;//
foreach (var item in clientListtemp)
{
byte[] arrMsg = Encoding.Default.GetBytes(str); ///获取键值(服务器),发送消息
try
{ item.Value.Send(arrMsg); }
catch (Exception ex)
{
RemoveClient(item.Key.ToString());
}
}
}
/// <summary>
/// 向单个客户端发送消息
/// </summary>
/// <param name="str">消息内容</param>
private void SendOnlgToClient(string str)
{
try
{
if (string.IsNullOrEmpty(str)) return;
Socket client = clientList[clientListShow.SelectedItem.ToString()] as Socket;
byte[] arrMsg = Encoding.Default.GetBytes(str); ///获取键值(服务器),发送消息
client.Send(arrMsg);
}
catch{ }
}
private void SendBut_Click(object sender, EventArgs e)
{
SendMsg(SendTxt.Text);
}
private void ClearLog_Click(object sender, EventArgs e)
{
listBox_log.Items.Clear();
}
private void SentToOnlyClient_Click(object sender, EventArgs e)
{
SendOnlgToClient(SendTxt.Text);
}
}
}
客户端:包含接收、发送、服务器断开状态
using System;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net.NetworkInformation;//ping
namespace TCPIP
{
public partial class TCP_Client : Form
{
static byte[] bufferCam = new byte[1024];
Socket socketCam;//= new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
public TCP_Client()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;//跨线程访问控件
}
/// <summary>
/// log显示
/// </summary>
/// <param name="str"></param>显示内容,函数内部自动加入时间
private void WrtLog(string str)
{
//LogShow.Invoke((EventHandler)delegate
//{
str = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff") + ":" + str;
listBox_log.Items.Add(str);
//});
}
/// <summary>
/// 通讯连接
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ConnectServer_Click(object sender, EventArgs e)
{
ConnectServer.Enabled = false;
WrtLog("开始连接。。。");
Ping p1 = new Ping();
PingReply PR = p1.Send(myIPAddress.Text, 500);
if (PR.Status == IPStatus.Success)
{
try
{
socketCam = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socketCam.Connect(myIPAddress.Text.Trim(), Convert.ToInt32(myServerPort.Text.Trim()));
//实现接受消息的方法
socketCam.BeginReceive(bufferCam, 0, bufferCam.Length, SocketFlags.None, new AsyncCallback(CamReceiveMessage), socketCam);
WrtLog("连接成功。");
}
catch (Exception ex)
{
WrtLog("连接异常");
ConnectServer.Enabled = true;
}
}
else
{
WrtLog("IP地址未连接,连接失败!");
ConnectServer.Enabled = true;
}
}
/// <summary>
/// 接收到服务器消息的方法
/// </summary>
/// <param name="ar"></param>
public void CamReceiveMessage(IAsyncResult ar)//接收到读码器数据信息
{
try
{
var socket = ar.AsyncState as Socket;
SocketError error;//ConnectionReset/Success
var length = socket.EndReceive(ar, out error);
if (length == 0)//服务器中断监听或网络中断(网络中断这一说法未经测试)
{
WrtLog("与服务器连接断开");
ConnectServer.Enabled = true;
socketCam.Shutdown(SocketShutdown.Both);
socketCam.Close();
return;
}
var message = Encoding.Default.GetString(bufferCam, 0, length);
//接收下一个消息
if (socketCam != null) socketCam.BeginReceive(bufferCam, 0, bufferCam.Length, SocketFlags.None, new AsyncCallback(CamReceiveMessage), socketCam);
//显示消息
if (length > 0)//正常接收到数据后处理
{
RevTxt.Invoke((EventHandler)delegate
{
RevTxt.Text = message;//接收正常消息
WrtLog(message);
});
}
}
catch (Exception ex)//服务器异常终止
{
if (ex.HelpLink != null) WrtLog("Exception:" + ex.Message);
ConnectServer.Enabled = true;
}
}
/// <summary>
/// 发送给服务器命令
/// </summary>
/// <param name="str"></param>
private void SendMsg(string str)
{
try
{
WrtLog("启动通讯发送!");
var message = str;
var outputBuffer = Encoding.Default.GetBytes(message);
socketCam.BeginSend(outputBuffer, 0, outputBuffer.Length, SocketFlags.None, null, null);
WrtLog("发送成功!");
}
catch (Exception ex)
{
WrtLog(ex.Message);
}
}
/// <summary>
/// 按钮发送给服务器数据
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SendBut_Click(object sender, EventArgs e)
{
SendMsg(SendTxt.Text);
}
private void DisConnect_Click(object sender, EventArgs e)
{
WrtLog("与服务器连接断开");
ConnectServer.Enabled = true;
socketCam.Disconnect(false);
socketCam.Close();
}
private void ClearLog_Click(object sender, EventArgs e)
{
listBox_log.Items.Clear();
}
}
}