聊天室服务端程序

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.IO;

namespace socket
{
public partial class 服务端 : Form
{
public 服务端()
{
InitializeComponent();
TextBox.CheckForIllegalCrossThreadCalls = false;//关闭对文本框的跨线程操作的检查
}

Socket socketWatch;
//保存了所有和客户端通信的套接字
Dictionary<string, Socket> dict = new Dictionary<string, Socket>();
private void button1_Click(object sender, EventArgs e)
{
//创建服务端负责监听的套接字,参数(使用IPV4寻址协议,使用流式连接,使用Tcp协议传输数据);
socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

//获得文本框的Ip地址对象
IPAddress address = IPAddress.Parse(textBox1.Text);

//创建包含ip和端口的网络节点对象
IPEndPoint endpoint = new IPEndPoint(address,int.Parse(textBox2.Text));

//将负责监听的套接字绑定到唯一的ip和端口上

try
{
socketWatch.Bind(endpoint);

}
catch (Exception ex)
{
textBox3.AppendText("异常:" + ex.Message + "\r\n");
return;
}

//设置监听队列的长度
socketWatch.Listen(10);

//开始监听客户端连接请求,注意:accept会阻断当前的线程,打开另外一个线程
//socketWatch.Accept();

//创建负责监听的线程
Thread threadWatch = new Thread(WatchConnecting);
threadWatch.IsBackground = true;
threadWatch.Start();
textBox3.AppendText("服务器监听成功!\r\n");//\r\n换行

}

void WatchConnecting()
{
while (true)//持续不断的监听新的客户端的连接请求
{
//一旦监听到客户端的请求,就返回一个负责和该客户端通信的套接字
Socket connection;
try
{
connection = socketWatch.Accept();
}
catch (Exception ex)
{
textBox3.AppendText("异常:" + ex.Message + "\r\n");
break;
}
//将与客户端通信的套接字对象connection添加到键值对集合中,并以客户端ip端口作为键
dict.Add(connection.RemoteEndPoint.ToString(), connection);
//向列表控件中添加一个客户端的ip端口字符串,作为客户端的唯一标识
listBox1.Items.Add(connection.RemoteEndPoint.ToString());
textBox3.AppendText("客户端连接成功!\r\n");
//connection.RemoteEndPoint中保存的是当前连接客户端的ip和端口

//为连接创建一个接收的线程
Thread rec = new Thread(receive);
rec.IsBackground = true;
rec.Start(connection);//启动线程,当前连接传入套接字
}
}
void receive(object conn)
{
Socket message=conn as Socket;
while (true)
{
byte[] msg = new byte[1024 * 1024 * 2];
//接收到的信息的长度
int length=-1;
try
{
length = message.Receive(msg);
}
catch (SocketException ex)
{
textBox3.AppendText("异常:" + ex.Message);
//从通信套接字集合中移除被中断的通信套接字对象
dict.Remove(message.RemoteEndPoint.ToString());
//从列表中清除中断的连接
listBox1.Items.Remove(message.RemoteEndPoint.ToString());
break;
}
catch (Exception ex)
{
textBox3.AppendText("异常:" + ex.Message);
break;
}
if (msg[0] == 0)
{
textBox3.AppendText("接收数据:" + System.Text.Encoding.UTF8.GetString(msg, 1, length-1) + "\r\n");

}
//在客户端显示
else if (msg[0] == 1)
{
SaveFileDialog sfd = new SaveFileDialog();
if (sfd.ShowDialog() == DialogResult.OK)
{
string path = sfd.FileName;//获取路径
//创建文件流,然后让文件流来根据路径创建一个文件
using (FileStream fs = new FileStream(path, FileMode.Create))
{
fs.Write(msg, 1, length - 1);
textBox3.AppendText("文件保存成功:" + path + "\r\n");
}
}

}
}
}

//发送信息
private void button2_Click(object sender, EventArgs e)
{
if (listBox1.Text=="")
{
MessageBox.Show("请选择好友");

}
else
{
//将要发送的字符串转成utf8对应的字节数组
byte[] message = System.Text.Encoding.UTF8.GetBytes(textBox4.Text);
//获得列表中选中key
string key = listBox1.Text;
//通过key找到字典集合中对应的与某个客户端通信套接字的send方法,发送数据给对方
dict[key].Send(message);
//connection.Send(message);//connection不能用socketWatch.Accept()代替
textBox3.AppendText("发送数据:" + textBox4.Text + "\r\n");
}
}

//群发信息
private void button3_Click(object sender, EventArgs e)
{
byte[] message = System.Text.Encoding.UTF8.GetBytes(textBox4.Text);
foreach (Socket s in dict.Values)
{
s.Send(message);
}
}
}
}

 

posted @ 2012-02-22 17:57  zwjyx_  阅读(651)  评论(0编辑  收藏  举报