SOCKET通讯
2012-08-15 18:08 C#与.NET探索者 阅读(228) 评论(0) 编辑 收藏 举报(一)
服务端
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;
using
System.Runtime.Serialization.Formatters.Binary;
namespace Server
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
//保存每一个客户端对应的负责通信的socket
Dictionary<string, Socket> dicConn =
new Dictionary<string, Socket>();
Socket socket;
private void btnStart_Click(object sender, EventArgs e)
{
btnStart.Enabled = false;
//创建一个负责监听的socket
socket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
//ip地址
IPAddress ip = IPAddress.Parse(txtServer.Text);
//ip地址 +
端口号
IPEndPoint point = new IPEndPoint(ip,
int.Parse(txtPort.Text));
try
{
//绑定ip地址+端口号
socket.Bind(point);
}
catch (Exception ex)
{
ShowMsg(ex.Message);
return;
}
//设置监听队列的大小
socket.Listen(10);
ShowMsg("开始监听");
Thread th = new
Thread(Listen);
//后台线程
th.IsBackground =
true;
th.Start();
}
void
Listen()
{
//不停监听客户端
while
(true)
{
Socket connect =
null;
try
{
//负责通信的socket
//Accept会阻塞线程
connect = socket.Accept();
cboUsers.Items.Add(connect.RemoteEndPoint.ToString());
//
dicConn.Add(connect.RemoteEndPoint.ToString(),
connect);
ShowMsg("\r\n" +
connect.RemoteEndPoint.ToString() + "连接!!");
}
catch (Exception ex)
{
ShowMsg("\r\n" + ex.Message);
return;
}
//不停的接收客户端发来的消息
Thread th = new
Thread(RecMsg);
th.IsBackground = true;
th.Start(connect);
}
}
void
RecMsg(object o)
{
Socket connect = o as
Socket;
//不停的接收客户端发来的消息
while
(true)
{
try
{
//接收消息
byte[] buffer = new
byte[1024 * 1024 * 5];
//length实际接收的字节数
int length =
connect.Receive(buffer);
string msg =
System.Text.Encoding.GetEncoding("gbk").GetString(buffer, 0,
length);
ShowMsg("\r\n" +
connect.RemoteEndPoint.ToString() + ":" + msg);
}
catch (Exception ex)
{
ShowMsg("\r\n" + ex.Message);
break;
}
}
}
//显示消息
void ShowMsg(string msg)
{
txtLog.Text += msg;
}
private void
Form1_Load(object sender, EventArgs e)
{
}
//服务器给客户端发送消息
private void btnSend_Click(object sender, EventArgs
e)
{
try
{
//文字的字节数组
byte[] buffer =
System.Text.Encoding.GetEncoding("gbk").GetBytes(txtMsg.Text);
//List<byte> list = new List<byte>();
//list.Add(0); //第一个字节 标示是文字
//list.AddRange(buffer);
//创建要发送的对象
Common.MyClass my = new Common.MyClass();
my.Type =
0;//第一个字节 标示是文字
my.Buffer = buffer;
//序列化对象,返回字节数组
string endpoint =
cboUsers.Text;
//获取客户端对应的socket
dicConn[endpoint].Send(Serialize(my));
}
catch
(Exception ex)
{
ShowMsg(ex.Message +
"\r\n");
}
}
//选择文件
private void btnSelect_Click(object sender, EventArgs
e)
{
OpenFileDialog ofd = new
OpenFileDialog();
if (ofd.ShowDialog() ==
System.Windows.Forms.DialogResult.OK)
{
txtPath.Text = ofd.FileName;
}
}
//发送文件
private void btnSendFile_Click(object sender, EventArgs
e)
{
using (FileStream fs = new
FileStream(txtPath.Text, FileMode.Open))
{
byte[] buffer = new byte[1024*1024*5];
int length =
fs.Read(buffer, 0, buffer.Length);
////".jpg" 10字节
第一个字节 0/1 后9个字节保存文件的类型
//List<byte> list = new
List<byte>();
//list.Add(1); //第一个字节 1
标示是文件
//list.AddRange(buffer);
List<byte> list = new List<byte>();
for (int i =
0; i < length; i++)
{
list.Add(buffer[i]);
}
Common.MyClass
my = new Common.MyClass();
my.Type = 1;
my.Buffer = list.ToArray();
try
{
//发送
string endpoint =
cboUsers.Text;
//获取客户端对应的socket
dicConn[endpoint].Send(Serialize(my));
}
catch (Exception ex)
{
ShowMsg(ex.Message + "\r\n");
}
}
}
//发送震动
private void
btnZD_Click(object sender, EventArgs e)
{
byte[]
buffer = new byte[1]; //标志位 2震动
buffer[0] = 2;
try
{
//发送
string endpoint
= cboUsers.Text;
//获取客户端对应的socket
dicConn[endpoint].Send(buffer);
}
catch (Exception
ex)
{
ShowMsg(ex.Message +
"\r\n");
}
}
byte[]
Serialize(Common.MyClass my)
{
using (MemoryStream
stream = new MemoryStream())
{
//把对象序列化到内存流
BinaryFormatter bf = new
BinaryFormatter();
bf.Serialize(stream,
my);
//设置流的起始位置
stream.Position =
0;
//把流转换成字节数组
byte[] buffer = new
byte[stream.Length];
stream.Read(buffer, 0,
buffer.Length);
return buffer;
}
}
}
}
(二)
客户端
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;
using
System.Net.Sockets;
using System.Threading;
using System.IO;
using
System.Runtime.Serialization.Formatters.Binary;
namespace Client
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
Socket
client;
private void btnStart_Click(object sender, EventArgs
e)
{
btnStart.Enabled = false;
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
IPAddress ip =
IPAddress.Parse(txtServer.Text);
IPEndPoint point = new
IPEndPoint(ip, int.Parse(txtPort.Text));
try
{
//连接服务器
client.Connect(point);
ShowMsg("连接成功");
this.Text += " " +
client.LocalEndPoint.ToString();
//接收消息
Thread th = new Thread(RecMsg);
th.IsBackground = true;
th.Start();
}
catch (Exception ex)
{
ShowMsg(ex.Message);
}
}
//接收服务器发送过来的消息
void RecMsg()
{
while
(true)
{
try
{
byte[] buffer = new byte[1024 * 1024 *
5];
//length实际接收的字节个数
int length =
client.Receive(buffer);
////没有数据直接返回
//if (buffer.Length <=
0)
//{
//
continue;
//}
//int type =
buffer[0];// 读取标示位
Common.MyClass my =
DeSerialize(buffer, length);
if (my ==
null)
{
continue;
}
//接收的是文字消息
if (my.Type == 0)
{
string msg =
System.Text.Encoding.GetEncoding("gbk").GetString(my.Buffer,0,my.Buffer.Length);
ShowMsg(client.RemoteEndPoint + ":" + msg);
}
////接收的是文件
else if (my.Type ==
1)
{
//提示是否接收文件
if (MessageBox.Show("是否接收文件", "提示",
MessageBoxButtons.OKCancel, MessageBoxIcon.Information) ==
System.Windows.Forms.DialogResult.OK)
{
//选择文件保存的位置
SaveFileDialog sfd = new SaveFileDialog();
if
(sfd.ShowDialog() ==
System.Windows.Forms.DialogResult.OK)
{
//要保存的文件的路径
string path =
sfd.FileName;
using (FileStream fs = new
FileStream(path, FileMode.Create))
{
//保存文件
fs.Write(my.Buffer, 0,
my.Buffer.Length);
}
}
}
}
//窗口震动
else if (my.Type == 2)
{
this.TopMost = true;
ZD();
}
}
catch (Exception
ex)
{
ShowMsg(ex.Message);
break;
}
}
}
private void btnSend_Click(object
sender, EventArgs e)
{
try
{
byte[] buffer =
System.Text.Encoding.GetEncoding("gbk").GetBytes(txtMsg.Text);
client.Send(buffer);
}
catch (Exception
ex)
{
ShowMsg(ex.Message);
}
}
//显示消息
void ShowMsg(string msg)
{
txtLog.Text += msg + "\r\n";
}
//窗口震动
void ZD()
{
for (int i = 0; i <
10; i++)
{
Test();
System.Threading.Thread.Sleep(50);
}
}
string dir = "top";
void Test()
{
if (dir
== "top")
{
this.Location = new
Point(this.Location.X + 10, this.Location.Y - 10);
dir =
"bottom";
}
else
{
dir = "top";
this.Location = new
Point(this.Location.X - 10, this.Location.Y + 10);
}
}
/// <summary>
/// 反序列化
///
</summary>
/// <param
name="buffer">反序列化的内容</param>
/// <param
name="length">有效的字节个数</param>
///
<returns></returns>
Common.MyClass DeSerialize(byte[]
buffer, int length)
{
BinaryFormatter bf = new
BinaryFormatter();
//把字节数组的内容读到内存流中
using (MemoryStream ms = new
MemoryStream())
{
ms.Write(buffer, 0,
length);
//设置流的起始位置
ms.Position =
0;
Common.MyClass my = bf.Deserialize(ms) as
Common.MyClass;
return my;
}
}
}
}