这次写一下Socket客户端,
在此之前先分享一下我找到的一张图
这张图和之前我画的服务器端和客户端之间的通信基本相同,不过这张图更可信一点。
下面就来写一下左面的客户端
下面直接贴代码了
public MainFrm()
{
InitializeComponent();
}
private Socket socket;
private void btnConn_Click(object sender, EventArgs e)
{
//创建一个Socket对象
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
txtMsgShow("正在努力链接服务器端。。。。");
//等待期间需要处理异常
try
{
//连接服务器
clientSocket.Connect(IPAddress.Parse(txtIP.Text), int.Parse(txtPort.Text));
}
catch (Exception)
{
Thread.Sleep(3000);
MessageBox.Show("连接失败!请重新连接。。。");
return;
}
socket = clientSocket;
txtMsgShow(string.Format("{0}服务器端已经连接成功\r\n",socket.RemoteEndPoint));
//开启另一个线程接收数据
ThreadPool.QueueUserWorkItem(new WaitCallback(ReceiveMsgFromServer), socket);
}
//接收数据
private void ReceiveMsgFromServer(object state)
{
Socket socket = (Socket)state;
int count=0;
//1M缓存区
byte[] recByte = new byte[1024 * 1024];
while (true)
{
try
{
count = socket.Receive(recByte, 0, recByte.Length, SocketFlags.None);
}
catch
{
txtMsgShow(string.Format("来自服务器端的消息:对方非正常退出了\r\n{0}", txtMsg.Text));
StopConnect();
return;
}
//判断一下服务器端是否正常退出
//正常退出
if (count <= 0)
{
txtMsgShow(string.Format("来自服务器端的消息:对方正常退出了{0}",txtMsg.Text));
StopConnect();
return;
}
//然后将缓存区中的byte转换成string在msg中显示出来
string str = Encoding.Default.GetString(recByte, 0, count);
txtMsgShow(string.Format("来自服务器端的消息:{1}\r\n{0}", txtMsg.Text, str));
}
}
//发送数据
private void btnSend_Click(object sender, EventArgs e)
{
if (socket.Connected)
{
byte[] sendByte = Encoding.Default.GetBytes(txtSend.Text);
socket.Send(sendByte,0,sendByte.Length,SocketFlags.None);
txtMsgShow(string.Format("你发送的消息:{0}\r\n{1}", txtSend.Text,txtMsg.Text));
//清空发送栏
txtSend.Text = "";
}
}
//用于显示接收连接情况
private void txtMsgShow(string str)
{
if (txtMsg.InvokeRequired)
{
txtMsg.Invoke(new Action<string>((s) => {
txtMsg.Text = s;
}),str);
}
else
{
txtMsg.Text = str;
}
}
//关闭连接
private void StopConnect()
{
try
{
if (socket.Connected)
{
socket.Shutdown(SocketShutdown.Both);
socket.Close(100);
}
}
//不管了
catch
{
}
}
private void MainFrm_FormClosing(object sender, FormClosingEventArgs e)
{
StopConnect();
}
}
这里有两点需要注意:
(1)客户端的Socket会自动分配一个随机的端口,所以在IP一栏填服务器主机的IP就行
(2)如果你是调试进行的测试,在关闭客户端时,会报一个创建句柄出错的异常,
是这句话的异常
txtMsgShow(string.Format("来自服务器端的消息:对方非正常退出了\r\n{0}", txtMsg.Text));
因为你已经关闭窗体,所以不可能再在txtbox中显示消息。
不过你可以不用理会这个异常,因为,真正使用exe时,窗体已经关闭,不可能再有什么异常。
结合之前写过的服务器端就可以互相通信了。