服务器端
=====================================
using System;
using System.Collections;
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;
namespace SocketServer
{
public partial class Form1 : Form
{
private IPAddress serverip = IPAddress.Parse("127.0.0.1");//以本机作测试
int port = 8000;
private IPEndPoint serverfulladdr;//完整终端地址
private Socket sock;
private System.Timers .Timer mytimer;
private ArrayList alsock;//当建立了多个连接时用于保存连接
public Form1()
{
InitializeComponent();
Start();
}
void Start()
{
try
{
serverfulladdr = new IPEndPoint(serverip, port);//取端口号1000
//构造socket对象,套接字类型为“流套接字”,指定五元组中的协议元
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//指定五元组中的本地二元,即本地主机地址和端口号
sock.Bind(serverfulladdr);
//监听是否有连接传入,指定挂起的连接队列的最大值为20
sock.Listen(20);
alsock = new ArrayList();
//构造定时器,时间间隙为1秒,即每隔一秒执行一次accept()方法,以获取连接请求队列中//第一个挂起的连接请求
mytimer = new System.Timers.Timer(1000);
mytimer.Elapsed += new System.Timers.ElapsedEventHandler(mytimer_elapsed);
mytimer.Enabled = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message );
}
}
private void btstart_click(object sender, EventArgs e)
{
Start();
}
private void mytimer_elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
mytimer.Enabled = false;
//执行accept(),当挂起队列为空时将阻塞本线程,同时由于上一语句,定时器将停止,直//至有连接传入
Socket acceptsock = sock.Accept();
//将accept()产生的socket对象存入arraylist
alsock.Add(acceptsock);
// 构造threading.timer对象,这将导致程序另启线程。线程将执行回调函数,该委托限制//函数参数须为object型。threading.timer构造器的第二个参数即传入回调函数的参数;第//三个参数指定调用回调函数之前的延时,取0则立即启动;最后一个参数指定调用回调函数//的时间间隔,取0则只执行一次。
System.Threading.Timer ti = new System.Threading.Timer(new TimerCallback(receivemsg), acceptsock, 0, 0);
mytimer.Enabled = true;
}
private void receivemsg(object obj)
{
Socket acceptsock = (Socket)obj;
try
{
while (true)
{
byte[] bytearray = new byte[100];
acceptsock.Receive(bytearray);//接收数据
//将字节数组转成字符串
string strrec = System.Text.Encoding.UTF8.GetString(bytearray);
if (this.rtbreceive.InvokeRequired)
{
this.rtbreceive.Invoke(new EventHandler(changericktextbox), new object[] { strrec, EventArgs.Empty });
}
}
}
catch(Exception ex)
{
acceptsock.Close();
MessageBox.Show("s:receive message error"+ex.Message );
}
}
private void changericktextbox(object obj,EventArgs e)
{
string s = System.Convert.ToString(obj);
this.rtbreceive.AppendText(s + Environment.NewLine );
}
private void btsend_click(object sender, EventArgs e)
{
Socket sc=null;
byte[] bytesend = System.Text.Encoding.UTF8 .GetBytes(this.tbsend.Text.ToCharArray());
try
{
//同时存在若干个客户端连接时,在textbox1中输入要发送的是哪个连接
int index = int.Parse(this.textbox1.Text.Trim());
sc = (Socket)alsock[index - 1];
//发送数据
sc.Send(bytesend);
}
catch(Exception ex)
{
if(sc != null)
{
sc.Close();
}
MessageBox.Show("s:send message error"+ex.Message );
}
}
private void btclose_click(object sender, EventArgs e)
{
try
{
Application.Exit();
}
catch (Exception ex)
{
MessageBox.Show("s:close socket error" + ex.Message );
}
}
}
}
========================================
客户端
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 ;
namespace SocketApp
{
public partial class FormMain : Form
{
Socket connectSocket;
//Socket client;
byte[] bytes = new byte[1024];
delegate void listboxDel(string s);
listboxDel listboxdel;
delegate void richTextBoxDel(string s);
richTextBoxDel richtextboxdel;
string IP = "127.0.0.1";//"192.168.1.168";
int port = 10000;
public FormMain()
{
InitializeComponent();
textBoxContent.Focus();
listboxdel = new listboxDel(listbox);
richtextboxdel = new richTextBoxDel(richtextbox);
//为连接指派线程
Thread threadConnect = new Thread(new ThreadStart(Connect));
threadConnect.Start();
}
#region 异步访问控件代理
public void listbox(string str)
{
listBox1.Items.Add(str);
listBox1.SelectedIndex = listBox1.Items.Count - 1;
listBox1.ClearSelected();
// richTextBox1.Text = richTextBox1.Text +"\r" +str;
}
/// <summary>
/// 代理
/// </summary>
/// <param name="str"></param>
public void richtextbox(string str)
{
richTextBox1.Text = str;
}
#endregion
#region 与服务器连接
//连接方法
public void Connect()
{
try
{
//建立连接socket
connectSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//开始异步连接
connectSocket.BeginConnect(IPAddress.Parse(IP),
port,
new AsyncCallback(ConnectCallback), //定义回调函数代理
connectSocket); //传递给回调函数的状态
}
catch (Exception e)
{
//MessageBox.Show(e.Message);
this.richTextBox1.Invoke(richtextboxdel, "Connect:" + e.ToString());
}
}
//连接方法的回调函数
private void ConnectCallback(IAsyncResult ar)
{
try
{
//从传递的状态中获取套接字,创建一个客户端套接字
Socket client = (Socket)ar.AsyncState;
//完成挂起的连接操作
client.EndConnect(ar);
listBox1.Invoke(listboxdel, "连接服务器成功,可以开始通话!");
client.BeginReceive(bytes, 0, 1000, 0, new AsyncCallback(receivecallback), client);
}
catch (Exception e)
{
this.richTextBox1.Invoke(richtextboxdel, "ConnectCallback:" + e.ToString());
//Console.WriteLine(e.ToString());
}
}
#endregion
#region 发送数据之后保持接受数据
public void receivecallback(IAsyncResult ar)
{
try
{
Socket client = (Socket)ar.AsyncState;
int length = client.EndReceive(ar);
string str = Encoding.UTF8.GetString(bytes, 0, length);
if (!string.IsNullOrEmpty(str))
{
listBox1.Invoke(listboxdel, str);
}
//继续访问服务器,及时 接受他人发送的数据
client.BeginReceive(bytes, 0, 1000, 0, new AsyncCallback(receivecallback), client);
}
catch (Exception e)
{
this.richTextBox1.Invoke(richtextboxdel, "receivecallback:" + e.ToString());
}
}
#endregion
private void button1_Click(object sender, EventArgs e)
{
//Send(textBoxUser.Text + ":" + textBoxContent.Text);
string ss = textBoxUser.Text + ":" + textBoxContent.Text;
Send(ss);
}
#region 发送数据
//发送方法
private void Send(String data)
{
//使用ASCII转换字符串为字节序列
byte[] byteData = Encoding.UTF8.GetBytes(data); //将字符串转换成字节序列
//开始向远端设备发送数据
connectSocket.BeginSend(byteData, 0, byteData.Length, SocketFlags.None, new AsyncCallback(SendCallback), connectSocket);
}
//发送方法的回调函数 //本季记录发送内容
private void SendCallback(IAsyncResult ar)
{
try
{
//从传递的状态中获取套接字,创建一个客户端套接字
Socket client = (Socket)ar.AsyncState;
//结束异步数据传输操作,返回传输的字节数
int bytesSent = client.EndSend(ar);
string ss = textBoxUser.Text + ":" + textBoxContent.Text;
listBox1.Invoke(listboxdel, ss);
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
}
}
#endregion
}
}