using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace _001_Server
{
public partial class FrmServer : Form
{
public FrmServer()
{
InitializeComponent();
}
private void FrmServer_Load(object sender, EventArgs e)
{
txtIp.Text = GetLocalIp.IpAddress();
txtPort.Text = "5000";
//关闭对文本框的非法线程操作检查
Control.CheckForIllegalCrossThreadCalls = false;
}
private void btnStartServer_Click(object sender, EventArgs e)
{
try
{
//1.创建监听的Socket
Socket listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//2.获取当前Ip地址
IPAddress ip = IPAddress.Parse(txtIp.Text);
//3.组成IP地址和Port号
IPEndPoint point = new IPEndPoint(ip, int.Parse(txtPort.Text));
//4.服务器开始对当前应用程序进行监听 (负责监听的Socket绑定IP地址和端口号)
listenSocket.Bind(point);
//5.设置监听队列
listenSocket.Listen(10); //监听队列挂起的最大长度
//6.显示监听成功的信息
ShowReceiveMsg("监听成功,正在等待客户端的连接......");
//7.接收客户端发送过来的信息
//定义线程
Thread th = new Thread(ReConnClientMsg);
//将线程设置为后台线程 (防止影响UI线程)
th.IsBackground = true;
//传入参数 并启动线程
th.Start(listenSocket);
}
catch { }
}
//定义键值对集合 存放连接服务器的客户端的 ip地址 和 Socket 信息
Dictionary<string, Socket> dicSocketList = new Dictionary<string, Socket>();
private void ReConnClientMsg(object socketInfo)
{
try
{
//循环 不停的刷新来自客户端的信息
while (true)
{
//类型转换
Socket listenSocket = socketInfo as Socket;
//1.新建负责和客户端建立连接的 Socket
Socket reConnClientSocket = listenSocket.Accept();
//给键值对集合添加 连接服务器的客户端的 ip 地址 和 Socket 信息
dicSocketList.Add(reConnClientSocket.RemoteEndPoint.ToString(), reConnClientSocket);
//给下拉选框中添加 连接服务器客户端的 ip 地址 和端口号
cmbAddressList.Items.Add(reConnClientSocket.RemoteEndPoint.ToString());
//2.显示成功连接客户端的信息
ShowReceiveMsg(reConnClientSocket.RemoteEndPoint.ToString() + ": 连接成功!!!");
//3.连接成功后开始接收来自客户端的信息
Thread th = new Thread(ReClientMsg); //这里的ReclientMsg 是将 ReClientMsg()方法,当作 参数使用
//将线程设置为后台线程
th.IsBackground = true;
//启动线程
th.Start(reConnClientSocket);
}
}
catch { }
}
private void ReClientMsg(object sockInfo) //使用线程调用方法是 参数必须是Object 类型
{
//类型转换
Socket ReClientMsgInfo = sockInfo as Socket;
try
{
while (true)
{
//1.新建缓冲区
byte[] buffer = new byte[1024 * 1024 * 5];
//2.将来自客户端的数据放入缓冲区中
int byteNums = ReClientMsgInfo.Receive(buffer);
//如果接收数据的字节大小为0 则终止在聊天区域显示
if (byteNums == 0) return;
//3.定义变量,将缓冲区中的数据转换成字符串
string msg = Encoding.UTF8.GetString(buffer, 0, byteNums);
//4.显示接收到的信息
ShowReceiveMsg(ReClientMsgInfo.RemoteEndPoint.ToString() + ": " + msg);
}
}
catch { }
}
private void btnSendMsg_Click(object sender, EventArgs e)
{
string ip = string.Empty;
try
{
//拿到下拉选框中的IP地址
ip = cmbAddressList.SelectedItem.ToString();
}
catch (Exception)
{
MessageBox.Show("请在地址选择要发送信息的对象", "提示:", MessageBoxButtons.OK, MessageBoxIcon.Error);
#region 三个参数的含义
//第一个参数是:提示内容
//第二个参数是:提示框标题
//的三个参数是:突时框中的错误图标
#endregion
return;
}
if (string.IsNullOrEmpty(txtSendMsg.Text.Trim().ToString()))
{
MessageBox.Show("消息内容不能为空", "提示:", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
//将待发送的信息转换为字节数组
byte[] buffer = Encoding.UTF8.GetBytes(txtSendMsg.Text.Trim());
//给客户端发送消息
dicSocketList[ip].Send(buffer);
//在聊天区域显示服务端发送的信息
ShowSendMsg(txtSendMsg.Text.Trim());
//给客户端发送一次信息清空一次文本框中的信息
txtSendMsg.Clear();
}
#region 显示信息
public void ShowReceiveMsg(string str)
{
txtChatList.AppendText(DateTime.Now.ToString() + "\r\n" + str + "\r\n");
}
public void ShowSendMsg(string str)
{
txtChatList.AppendText(DateTime.Now.ToString() + "\r\n" + "我: " + str + "\r\n");
}
#endregion
}
}
五.服务端获取本机IP地址代码
[C#] 纯文本查看复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace _001_Server
{
public class GetLocalIp
{
public static string IpAddress()
{
try
{
//1.得到主机名
string hostName = Dns.GetHostName();
//2.新建IpHostEntry容器,存放Ip地址
IPHostEntry hostEntry = Dns.GetHostEntry(hostName);
//3.从hostEntry容器中得到IPV4地址
for (int i = 0; i < hostEntry.AddressList.Length; i++)
{
//如果存放IP地址中的某一个成员是IPV4地址则返回这个IP地址
if (hostEntry.AddressList[i].AddressFamily==AddressFamily.InterNetwork)
{
return hostEntry.AddressList[i].ToString();
}
}
}
catch (Exception ex)
{
return ex.Message;
}
return "";
}
}
}