using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Server
{
public partial class Form1 : Form
{
//这里声明多个套接字是为了在连接,接收数据,发送数据的函数中不发生混乱,同时方便关闭
public static Socket ServerSocket; //声明用于监听的套接字
public static Socket socketAccept; //声明绑定了客户端的套接字
public static Socket socket; //声明用于与某一个客户端通信的套接字
public static int SFlag = 0; //连接成功标志
public static int CFlag = 0; //客户端关闭的标志
Thread th1; //声明线程1
Thread th2; //声明线程2
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Control.CheckForIllegalCrossThreadCalls = false; //执行新线程时跨线程资源访问检查会提示报错,所以这里关闭检测
}
/*****************************************************************/
void Listen(Object sk)
{
socketAccept = sk as Socket; //创建一个与客户端对接的套接字
try
{
while (true)
{
//GNFlag如果为1就进行中断连接,使用在标志为是为了保证能够顺利关闭服务器端
/*
* 当客户端关闭一次后,如果没有这个标志位会使得服务器端一直卡在中断的位置
* 如果服务器端一直卡在中断的位置就不能顺利关闭服务器端
*/
//4.阻塞到有client连接
socket = socketAccept.Accept();
CFlag = 0; //连接成功,将客户端关闭标志设置为0
SFlag = 1; //当连接成功,将连接成功标志设置为1
richTextBox1.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ") + textBox1.Text + "连接成功";
richTextBox1.Text += "\r\n";
//开启第二个线程接收客户端数据
th2 = new Thread(Receive); //线程绑定Receive函数
th2.IsBackground = true; //运行线程在后台执行
th2.Start(socket); //Start里面的参数是Listen函数所需要的参数,这里传送的是用于通信的Socket对象
}
}
catch
{
//MessageBox.Show("没有连接上客户端");
}
}
void Receive(Object sk)
{
socket = sk as Socket; //创建用于通信的套接字
while (true)
{
try
{
if (CFlag == 0 && SFlag == 1)
{
//5.接收数据
byte[] recieve = new byte[1024];
int len = socket.Receive(recieve);
//6.打印接收数据
if (recieve.Length > 0)
{
//如果接收到客户端停止的标志
if (Encoding.ASCII.GetString(recieve, 0, len) == "*close*")
{
richTextBox1.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ") + "客户端已退出" + "\n";
CFlag = 1; //将客户端关闭标志设置为1
break; //退出循环
}
//打印接收数据
richTextBox1.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ") + "接收:";
richTextBox1.Text += Encoding.ASCII.GetString(recieve, 0, len); //将字节数据根据ASCII码转成字符串
richTextBox1.Text += "\r\n";
}
}
else
{
break; //跳出循环
}
}
catch
{
MessageBox.Show("收不到信息");
}
}
}
private void button_Send(object sender, EventArgs e)
{
//SFlag标志连接成功,同时当客户端是打开的时候才能发送数据
if (SFlag == 1 && CFlag == 0)
{
byte[] send = new byte[1024];
send = Encoding.ASCII.GetBytes(richTextBox2.Text); //将字符串转成字节格式发送
socket.Send(send); //调用Send()向客户端发送数据
//打印发送时间和发送的数据
richTextBox1.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ") + "发送:";
richTextBox1.Text += richTextBox2.Text + "\n";
richTextBox2.Clear(); //清除发送框
}
}
private void textBox3_TextChanged(object sender, EventArgs e)
{
}
private void textBox_Addr(object sender, EventArgs e)
{
}
private void button_Accpet(object sender, EventArgs e)
{
ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //创建用于通信的套接字
richTextBox1.Text += "正在连接...\n";
button1.Enabled = false; //禁止操作接收按钮
//1.绑定IP和Port
IPAddress IP = IPAddress.Parse(textBox1.Text);
int Port = int.Parse(textBox2.Text);
//IPAddress ip = IPAddress.Any;
IPEndPoint iPEndPoint = new IPEndPoint(IP, Port);
try
{
//2.使用Bind()进行绑定
ServerSocket.Bind(iPEndPoint);
//3.开启监听
//Listen(int backlog); backlog:监听数量
ServerSocket.Listen(10);
/*
* tip:
* Accept会阻碍主线程的运行,一直在等待客户端的请求,
* 客户端如果不接入,它就会一直在这里等着,主线程卡死
* 所以开启一个新线程接收客户单请求
*/
//开启线程Accept进行通信的客户端socket
th1 = new Thread(Listen); //线程绑定Listen函数
th1.IsBackground = true; //运行线程在后台执行
th1.Start(ServerSocket); //Start里面的参数是Listen函数所需要的参数,这里传送的是用于通信的Socket对象
Console.WriteLine("1");
}
catch
{
MessageBox.Show("服务器出问题了");
}
}
private void textBox_Port(object sender, EventArgs e)
{
}
private void button_Close(object sender, EventArgs e)
{
//若连接上了客户端需要关闭线程2和socket,没连接上客户端直接关闭线程1和其他套接字
if (CFlag == 1)
{
th2.Abort(); //关闭线程2
socket.Close(); //关闭用于通信的套接字
}
ServerSocket.Close(); //关闭用于连接的套接字
socketAccept.Close(); //关闭与客户端绑定的套接字
th1.Abort(); //关闭线程1
CFlag = 0; //将客户端标志重新设置为0,在进行连接时表示是打开的状态
SFlag = 0; //将连接成功标志程序设置为0,表示退出连接
button1.Enabled = true;
richTextBox1.Text += DateTime.Now.ToString("yy-MM-dd hh:mm:ss ");
richTextBox1.Text += "服务器已关闭" + "\n";
MessageBox.Show("服务器已关闭");
}
private void richTextBox_Receive(object sender, EventArgs e)
{
}
private void richTextBox_Send(object sender, EventArgs e)
{
}
private void richTextBox2_Send_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)//如果输入的是回车键
{
this.button_Send(sender, e);//触发button事件
}
}
}
}
在csdn中找到一个socket的文章,但是没有异步操作,本篇文章加上异步操作