zl程序教程

您现在的位置是:首页 >  后端

当前栏目

C# Socket 线程

c#线程 socket
2023-09-14 09:02:11 时间
最初的版本是这样的:点击打开链接。但一直没有调好,所以就咨询了一下同事翔哥,最后初步搞定! 客户端代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq;

最初的版本是这样的:点击打开链接。但一直没有调好,所以就咨询了一下同事翔哥,最后初步搞定!

客户端代码:

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.Threading;

using System.Net;

using System.Diagnostics;

namespace SocketClient

 public partial class Client : Form

 Socket vsServerSocket;

 Thread vsClientThread;

 string strIP = "127.0.0.1";

 public delegate void PassString(string strMsg);

 int nPort = 9001;

 public Client()

 InitializeComponent();

 public void SetSendData(string strMsg)

 if (tBoxClientSend.InvokeRequired == true)

 PassString d = new PassString(SetSendData);

 this.Invoke(d, new object[] { strMsg });

 else

 tBoxClientSend.Text = strMsg;

 public void SetRecvData(string strMsg)

 if (tBoxClientReceive.InvokeRequired == true)

 PassString d = new PassString(SetRecvData);

 this.Invoke(d, new object[] { strMsg });

 else

 tBoxClientReceive.Text = strMsg;

 private void ClientHandle()

 string strRecv = string.Empty;

 //IPEndPoint其实就是一个IP地址和端口的绑定,可以代表一个服务,用来Socket通讯。

 //IPAddress类中有一个 Parse()方法,可以把点分的十进制IP表示转化成IPAddress类

 IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(strIP), nPort);

 //创建套接字实例

 //这里创建的时候用ProtocolType.Tcp,表示建立一个面向连接(TCP)的Socket

 vsServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

 //将所创建的套接字与IPEndPoint绑定

 vsServerSocket.Bind(ipep);

 catch (SocketException ex)

 MessageBox.Show("Connect Error: " + ex.Message);

 return;

 Byte[] buffer = new Byte[1024];

 //设置套接字为收听模式

 vsServerSocket.Listen(10);

 //循环监听 

 while (true)

 //接收服务器信息

 int bufLen = 0; 

 Socket vsClientSocket = vsServerSocket.Accept();

 bufLen=vsClientSocket.Receive(buffer);

 vsClientSocket.Send(Encoding.ASCII.GetBytes("aaaaa"), 5, SocketFlags.None);

 catch (Exception ex)

 MessageBox.Show("Receive Error:" + ex.Message); 

 strRecv = Encoding.ASCII.GetString(buffer, 0, bufLen);

 SetRecvData(strRecv); 

 //vsClientSocket.Shutdown(SocketShutdown.Both);

 //vsClientSocket.Close();

 //发送数据

 private void btnSend_Click(object sender, EventArgs e)

 byte[] data = new byte[1024];

 string ss = tBoxClientSend.Text;

 Socket centerClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

 IPEndPoint GsServer = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9002);

 centerClient.Connect(GsServer);

 centerClient.Send(Encoding.ASCII.GetBytes(ss));

 centerClient.Close();

 private void Client_Load(object sender, EventArgs e)

 //连接服务器

 //通过ThreadStart委托告诉子线程讲执行什么方法

 vsClientThread = new Thread(new ThreadStart(ClientHandle));

 vsClientThread.Start();

 //窗体关闭时杀死客户端进程

 private void Client_FormClosing(object sender, FormClosingEventArgs e)

 KillProcess();

 //杀死客户端进程

 private void KillProcess()

 Process[] processes = Process.GetProcessesByName("SocketClient");

 foreach (Process process in processes)

 process.Kill();

 break;

}
服务端代码:

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.Threading;

using System.Net.Sockets;

using System.Net;

using System.Diagnostics;

namespace SocketServer

 public partial class Server : Form

 Thread vsServerThread;

 Socket vsServerSocket; 

 string strIP = "127.0.0.1";

 public delegate void PassString(string strMsg); 

 int nPort = 9002;

 public Server()

 InitializeComponent();

 private void SeverSendData(string strMsg)

 //Control.InvokeRequired 属性,命名空间: System.Windows.Forms

 //获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。

 if (tBoxServerSend.InvokeRequired == true)

 //Control.Invoke 方法 (Delegate)

 //在拥有此控件的基础窗口句柄的线程上执行指定的委托。

 PassString d = new PassString(SeverSendData);

 this.Invoke(d, new object[] { strMsg });

 else

 tBoxServerSend.Text = strMsg;

 private void SeverRecvData(string strMsg)

 if (tBoxServerReceive.InvokeRequired == true)

 PassString d = new PassString(SeverRecvData);

 this.Invoke(d, new object[] { strMsg });

 else

 tBoxServerReceive.Text = strMsg;

 private void ServerStart()

 string strRecv = string.Empty;

 //创建IPEndPoint实例

 IPEndPoint ipep = new IPEndPoint(IPAddress.Parse(strIP), nPort);

 //创建一个套接字

 vsServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

 //将所创建的套接字与IPEndPoint绑定

 vsServerSocket.Bind(ipep);

 catch (Exception ee)

 MessageBox.Show(ee.ToString());

 return;

 //设置套接字为收听模式

 vsServerSocket.Listen(10);

 int bufLen = 0;

 //循环监听 

 while (true)

 //在套接字上接收接入的连接

 Socket vsClientSocket = vsServerSocket.Accept(); 

 Byte[] buffer = new Byte[1024];

 //在套接字上接收客户端发送的信息

 bufLen = vsClientSocket.Receive(buffer);

 vsClientSocket.Send(Encoding.ASCII.GetBytes("aaaaa"), 5, SocketFlags.None);

 if (bufLen == 0)

 continue; 

 //将指定字节数组中的一个字节序列解码为一个字符串。

 strRecv = Encoding.ASCII.GetString(buffer, 0, bufLen);

 SeverRecvData(strRecv.ToString());

 catch (Exception ex)

 MessageBox.Show("Listening Error: " + ex.Message);

 vsClientSocket.Close();

 vsServerSocket.Close();

 private void btnSend_Click(object sender, EventArgs e)

 byte[] data = new byte[1024];

 string ss = tBoxServerSend.Text;

 Socket centerClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

 IPEndPoint GsServer = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9001);

 centerClient.Connect(GsServer);

 centerClient.Send(Encoding.ASCII.GetBytes(ss));

 centerClient.Send(Encoding.ASCII.GetBytes(ss));

 //Thread.Sleep(100);

 //centerClient.Close();

 private void Server_Load(object sender, EventArgs e)

 vsServerThread = new Thread(new ThreadStart(ServerStart));

 vsServerThread.Start();

 //窗体关闭时杀死客户端进程

 private void Server_FormClosing(object sender, FormClosingEventArgs e)

 KillProcess();

 //杀死客户端进程

 private void KillProcess()

 Process[] processes = Process.GetProcessesByName("Server");

 foreach (Process process in processes)

 process.Kill();

 break;

}

效果如下:

客户端可以发送消息给服务端,服务端也可以发送消息给客户端。

缺点:

现在服务端只能连接一个客户端



为什么kill进程后socket一直处于FIN_WAIT_1状态 本文介绍一个因为conntrack内核参数设置和iptables规则设置的原因导致TCP连接不能正常关闭(socket一直处于FIN_WAIT_1状态)的案例,并介绍conntrack相关代码在conntrack表项超时后对新报文的处理逻辑。
/* 实现功能:通过epoll, 处理多个socket * 监听一个端口,监听到有链接时,添加到epoll_event * xs #include #include #include #include
关于Socket 多线程 的一篇好文章 http://www.kegel.com/c10k.html#topIt s time for web servers to handle ten thousand clients simultaneously, don t you think? After all, the web is a big place now.