实现简单的Socket聊天功能, 若应用在项目里,有些地方还需要优化.比如连接中断后我这里只是break跳出循化,没有重启线程再次连接;暂时只实现了发送string类型的消息,后续会添加发送rar,图片,音频等格式的数据.还有例如热键,多人聊天,群组等这些都没有完善,后续会进行优化
使用方法是服务端保证和客户端一致,点击监听.(代码里自动获取服务端主机的ipv4,这块需要的话可以添加个文本框设置服务端ip地址),客户端填写服务端ip和端口号,点击链接,显示连接成功后,就可以互发消息了.
代码下载地址 : https://download.csdn.net/download/m0_37137902/10916136
服务端界面
客户端界面
服务端代码
public partial class FormServer : Form
{
private Thread thread;
IPAddress localipv4;
private Socket sock;
private Socket acc;
public FormServer()
{
InitializeComponent();
}
/// <summary>
/// 获取本机IP
/// </summary>
private void GetIpAddress()
{
string hostName = Dns.GetHostName(); //获取本机名
localipv4 = Dns.GetHostAddresses(hostName).Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).First();//获取IPv4的地址
IPAddress localipv6 = Dns.GetHostAddresses(hostName).Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6).First();//获取IPv6地址
}
private void btn_monitor_Click(object sender, EventArgs e)
{
FormServer.CheckForIllegalCrossThreadCalls = false;
thread = new Thread(new ThreadStart(MonitorStart));
thread.Start();
}
/// <summary>
/// 监听客户端
/// </summary>
private void MonitorStart()
{
GetIpAddress();
IPEndPoint myServer = new IPEndPoint(localipv4, Convert.ToInt32(txt_port.Text));
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Bind(myServer);
sock.Listen(10);
acc = sock.Accept();
if (acc.Connected)
{
lab_con.Text = "与客户建立连接。";
while (acc.Connected)
{
try
{
Byte[] bt = new Byte[100];
acc.Receive(bt, bt.Length, 0); //接收来自绑定的 Socket 的数据,将数据置于bbb中
string message = System.Text.Encoding.Default.GetString(bt); //将字节数组中的数据转换于字符串;
SetContrlEnabel(message);
}
catch
{
MessageBox.Show("客户端已关闭");
break;
}
}
}
}
/// <summary>
/// 委托更改UI界面
/// </summary>
/// <param name="message"></param>
delegate void ContrlEnabelDelegate(string message);
private void SetContrlEnabel(string message)
{
if (richtxtbox_share.InvokeRequired)
{
Invoke(new ContrlEnabelDelegate(SetContrlEnabel), new object[] { message });
}
else
{
richtxtbox_share.AppendText(message+ "\r\n"); //显示于文本框
}
}
/// <summary>
/// 发送信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Send_Click(object sender, EventArgs e)
{
Byte[] bt = new Byte[100];
string message = localipv4.ToString() + ":" + richtxtbox_local.Text + "\r\n";
bt = System.Text.Encoding.Default.GetBytes(message.ToCharArray());
acc.Send(bt, bt.Length, 0);
//sock.Send(bt, bt.Length, 0);
richtxtbox_share.Text += localipv4.ToString() + ":" + richtxtbox_local.Text + "\r\n";
richtxtbox_local.Text = "";
richtxtbox_local.Focus();
}
private void FormServer_FormClosed(object sender, FormClosedEventArgs e)
{
System.Environment.Exit(0);
}
}
客户端代码
public partial class FormClient : Form
{
private Socket sock;
private Thread thread;
IPAddress localipv4;
public FormClient()
{
InitializeComponent();
}
private void FormClient_Load(object sender, EventArgs e)
{
GetIpAddress();
}
private void btn_connect_Click(object sender, EventArgs e)
{
IPAddress ip = IPAddress.Parse(txt_ServerIp.Text);
IPEndPoint myServer = new IPEndPoint(ip, Convert.ToInt32(txt_port.Text));
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Connect(myServer);
thread = new Thread(new ThreadStart(Access));
thread.Start();
lab_con.Text = "与主机" + txt_ServerIp.Text + "连接成功";
}
/// <summary>
/// 接收信息
/// </summary>
private void Access()
{
while (true)
{
try
{
Byte[] bt = new Byte[100];
sock.Receive(bt, bt.Length, 0);
string message = Encoding.Default.GetString(bt);
SetContrlEnabel(message);
}
catch
{
MessageBox.Show("服务端已关闭");
break;
}
}
}
/// <summary>
/// 获取本机IP
/// </summary>
private void GetIpAddress()
{
string hostName = Dns.GetHostName(); //获取本机名
localipv4 = Dns.GetHostAddresses(hostName).Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).First();//获取IPv4的地址
IPAddress localipv6 = Dns.GetHostAddresses(hostName).Where(ip => ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6).First();//获取IPv6地址
}
/// <summary>
/// 发送信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_Send_Click(object sender, EventArgs e)
{
Byte[] bt = new Byte[100];
string send = localipv4.ToString() + ":" + richtxtbox_local.Text + "\r\n";
bt = Encoding.Default.GetBytes(send.ToCharArray());
sock.Send(bt, bt.Length, 0);
richtxtbox_share.Text += localipv4.ToString() + ":" + richtxtbox_local.Text + "\r\n";
richtxtbox_local.Text = "";
richtxtbox_local.Focus();
}
/// <summary>
/// 委托更改UI界面
/// </summary>
/// <param name="message"></param>
delegate void ContrlEnabelDelegate(string message);
private void SetContrlEnabel(string message)
{
if (richtxtbox_share.InvokeRequired)
{
Invoke(new ContrlEnabelDelegate(SetContrlEnabel), new object[] { message});
}
else
{
richtxtbox_share.AppendText(message);
}
}
private void FormClient_FormClosed(object sender, FormClosedEventArgs e)
{
System.Environment.Exit(0);
}
}