socket实例
代码
环境:windows xp、vs2008
没有经过压力测试不知道最后效果怎么样
服务器端:
SocketThread2.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using System.Reflection;
using System.Windows.Forms;
using System.IO;
namespace WindowsFormsApplication1
{
/*
* 2.客戶端數量較多,但都是短連接的情況下,
* 短连接是指客户端的连接在处理完一次收发之后就产即断开的场景,比如说HTTP协议就是一种短连接。
* HTTP在客户端发出请求时建立一个 Socket连接,并通过Socket发出一个URL请求,
* 服务端在处理完这个请求并回发相应的页面后便会断开这个连接。那么在这种场景下我们也可以使用同步Socket来实现我们的需求。
* 以下示例方案中每一个连接都是短连接。而且顺序都是固定的。都是:接入->接收->发送这样的顺序,那么我们就可以在一个方法中完成整个处理.
*
* 首先我们创建了一个Socket用于侦听客户端的连接请求,接下我们创建了一个拥有30个线程的线程池。
* 并在每个线程中实现了Accept、 Receive、Send和Close(),以完成连接、接收、发送、关闭的操作。
*/
/*
* 处理说明
*
* 首先我们创建了一个Socket用于侦听客户端的连接请求,接下我们创建了一个拥有 30个线程的线程池。
* 并在每个线程中实现了Accept、Receive、Send和Close(),以完成连接、接收、发送、关闭的操作。
* 现在我们假设有一个客户连接到服务器了,这时会有一个线程Accept到这个请求,并开始接收客户端发送过来的数据,
* 接收到数据之后处理完发送给客户端,然后关闭这个连接,再次进入等待连接状态。
* 而其它29个线程由于没有Accept到这个请求,仍然处理等待接入状态。
*
*/
public delegate void AddListItemHandler(string value);
public class SocketThread2
{
private Socket listener;
public SocketThread2()
{
}
public void createsocket()
{
listener = listenerclass();
}
public Socket listenerclass()
{
//建立socket偵聽連接
listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
IPEndPoint locEP = new IPEndPoint(IPAddress.Any, 2000);
listener.Bind(locEP);
listener.Listen(100);
//建立一个线程池
ThreadPool.QueueUserWorkItem(new WaitCallback(ClientWorkThread));
/*
Thread[] ClientThreadList = new Thread[30];
for (int i = 0; i < 30; i++)
{
ClientThreadList[i] = new Thread(new ThreadStart(ClientWorkThread));
ClientThreadList[i].Start();
}
*/
}
catch (Exception ex)
{
logWrite("建立监控出错:"+ex.Message);
}
return listener;
}
//处理连接请求
private void ClientWorkThread(Object stateInfo)
{
byte[] buffer = new byte[8192];
try
{
while (true)
{
try
{
Socket socket = listener.Accept();
IPEndPoint remoEP = ((IPEndPoint)socket.RemoteEndPoint);
string recString = "接收到来自" + remoEP.Address.ToString() + "的连接。";
//Console.WriteLine(recString);
int receCount = socket.Receive(buffer);
if (receCount > 0)
{
//string recievestring = Encoding.Default.GetString(buffer, 0, receCount);
string recievestring = Encoding.GetEncoding("gb2312").GetString(buffer, 0, receCount);
recievestring = "sdfsdfs:" + recievestring;
byte[] sendbuffer = new byte[8192];
//sendbuffer = Encoding.ASCII.GetBytes(recievestring);
sendbuffer = Encoding.GetEncoding("gb2312").GetBytes(recievestring);
recString = "来自客户端" + remoEP.Address.ToString() + "的消息:" + recievestring;
//Console.WriteLine(recString);
AddListItemHandler addhandle = new AddListItemHandler(AddListItem);
addhandle.Invoke(recString); //调用窗体来执行委托
socket.Send(sendbuffer, sendbuffer.Length, SocketFlags.None);
}
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
catch (Exception ex)
{
logWrite("接收信息出错_1,循环停摆1分钟:" + ex.Message);
System.Threading.Thread.Sleep(60000);
}
}
}
catch (Exception ex)
{
logWrite("接收信息出错:" + ex.Message);
}
}
private void AddListItem(string value)
{
logWrite(value);
}
public void Dispose()
{
//if (listener.Connected)
//{
// listener.Close();
//}
listener = null;
}
public void logWrite(string errstr)
{
string filename = Application.ExecutablePath;
filename = Path.GetDirectoryName(filename) + "\\" + System.DateTime.Now.ToString("yyyyMMdd") + "log.txt";
try
{
string oldfile = Path.GetDirectoryName(filename) + "\\" + System.DateTime.Now.AddDays(-5).ToString("yyyyMMdd") + "log.txt";
if (File.Exists(oldfile))
{
File.Delete(oldfile);
}
FileStream fs1 = new FileStream(filename, FileMode.OpenOrCreate, FileAccess.ReadWrite);
StreamWriter rw = new StreamWriter(fs1, System.Text.Encoding.Default);
rw.BaseStream.Seek(0, SeekOrigin.End); //将文件指针设置到文件结尾
rw.WriteLine(errstr + " " + System.DateTime.Now.ToString());
rw.Close();
fs1.Close();
}
catch
{ }
}
}
}
form1.cs
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;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
SocketThread2 st = new SocketThread2();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
st.createsocket();
}
public void setlistvalue(string value)
{
listBox1.Items.Add(value);
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
st.Dispose();
st = null;
Application.Exit();
}
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
base.OnClosing(e);
Application.Exit();
}
}
}
客户端:
form1.cs
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;
namespace WindowsFormsApplication1_1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
StartClient();
}
private void StartClient()
{
// Data buffer for incoming data.
byte[] bytes = new byte[1024];
// Connect to a remote device.
try
{
// Establish the remote endpoint for the socket.
// This example uses port 11000 on the local computer.
/*
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
*/
IPAddress ipAddress = System.Net.IPAddress.Parse(textBox4.Text);
//IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 });
IPEndPoint remoteEP = new IPEndPoint(ipAddress, int.Parse(textBox3.Text));
// Create a TCP/IP socket.
Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// Connect the socket to the remote endpoint. Catch any errors.
try
{
sender.Connect(remoteEP);
Console.WriteLine("Socket connected to {0}", sender.RemoteEndPoint.ToString());
listBox1.Items.Add(sender.RemoteEndPoint.ToString());
// Encode the data string into a byte array.
//byte[] msg = Encoding.ASCII.GetBytes("This is a test<EOF>");
//byte[] msg = Encoding.ASCII.GetBytes(textBox1.Text);
byte[] msg = Encoding.GetEncoding("gb2312").GetBytes(textBox1.Text);
// Send the data through the socket.
int bytesSent = sender.Send(msg);
// Receive the response from the remote device.
int bytesRec = sender.Receive(bytes);
Console.WriteLine("Echoed test = {0}", Encoding.ASCII.GetString(bytes, 0, bytesRec));
listBox1.Items.Add(Encoding.GetEncoding("gb2312").GetString(bytes, 0, bytesRec));
textBox2.Text = Encoding.GetEncoding("gb2312").GetString(bytes, 0, bytesRec);
// Release the socket.
sender.Shutdown(SocketShutdown.Both);
sender.Close();
}
catch (ArgumentNullException ane)
{
Console.WriteLine("ArgumentNullException : {0}", ane.ToString());
}
catch (SocketException se)
{
Console.WriteLine("SocketException : {0}", se.ToString());
}
catch (Exception e)
{
Console.WriteLine("Unexpected exception : {0}", e.ToString());
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}