using
System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace TCP聊天室
... {
public partial class Form1 : Form
...{
private IPEndPoint MyServer;
private Socket sock;
private Thread myThread;
private Socket[] clientsock;
private int clientnum;
private byte[] buffer;
public Form1()
...{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
...{
MyServer = new IPEndPoint(IPAddress.Any, 10000);
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Bind(MyServer);
sock.Listen(10);
CheckForIllegalCrossThreadCalls = false;
clientsock = new Socket[65535];
clientnum = 0;
buffer = new byte[65535];
myThread = new Thread(recvaccept);
myThread.Start();
}
private void recvaccept()
...{
while (true)
...{
clientsock[clientnum] = sock.Accept();
clientsock[clientnum].BeginReceive(buffer, 0, buffer.Length, 0, new AsyncCallback(ReceiveCallback), clientsock[clientnum]);
clientlist.Items.Add(clientsock[clientnum].RemoteEndPoint.ToString());
clientnum++;
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
...{
sock.Close();
myThread.Abort();
}
private void ReceiveCallback(IAsyncResult ar)
...{
try
...{
Socket a = (Socket)ar.AsyncState;
int read = a.EndReceive(ar);
//clientlist.Items.Add(Encoding.ASCII.GetString(buffer,0,read));
for (int i = 0; i < clientnum; i++)
...{
if (clientsock[i].Connected)
...{
clientsock[i].Send(buffer, 0, read, 0);
}
}
a.BeginReceive(buffer, 0, buffer.Length, 0, new AsyncCallback(ReceiveCallback), a);
}
catch
...{ }
}
}
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace TCP聊天室
... {
public partial class Form1 : Form
...{
private IPEndPoint MyServer;
private Socket sock;
private Thread myThread;
private Socket[] clientsock;
private int clientnum;
private byte[] buffer;
public Form1()
...{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
...{
MyServer = new IPEndPoint(IPAddress.Any, 10000);
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
sock.Bind(MyServer);
sock.Listen(10);
CheckForIllegalCrossThreadCalls = false;
clientsock = new Socket[65535];
clientnum = 0;
buffer = new byte[65535];
myThread = new Thread(recvaccept);
myThread.Start();
}
private void recvaccept()
...{
while (true)
...{
clientsock[clientnum] = sock.Accept();
clientsock[clientnum].BeginReceive(buffer, 0, buffer.Length, 0, new AsyncCallback(ReceiveCallback), clientsock[clientnum]);
clientlist.Items.Add(clientsock[clientnum].RemoteEndPoint.ToString());
clientnum++;
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
...{
sock.Close();
myThread.Abort();
}
private void ReceiveCallback(IAsyncResult ar)
...{
try
...{
Socket a = (Socket)ar.AsyncState;
int read = a.EndReceive(ar);
//clientlist.Items.Add(Encoding.ASCII.GetString(buffer,0,read));
for (int i = 0; i < clientnum; i++)
...{
if (clientsock[i].Connected)
...{
clientsock[i].Send(buffer, 0, read, 0);
}
}
a.BeginReceive(buffer, 0, buffer.Length, 0, new AsyncCallback(ReceiveCallback), a);
}
catch
...{ }
}
}
}
以上是一个C#聊天室服务端的原代码.代码简单粗糙,在修正了几个bug以后总算能够运行了.值得注意的地方就是BeginReceive和EndReceive这两个异步方法.在接受信息后将信息转发给所有聊天室客户端.
以及每一次连接都将新建一个socket连接.
以下是一个客户端和服务端的应用层协议.就是先发送一个4个字节的包头,包含包体字节数,来确定包是否正确接收完
private
void
AcceptMessage()
... {
Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
NetworkStream stream = new NetworkStream(socket);
while (true)
...{
try
...{
byte[] datasize = new byte[4];
stream.Read(datasize, 0, 4);
int size = BitConverter.ToInt32(datasize, 0);
byte[] message = new byte[size];
int dataleft = size;
int start = 0;
while (dataleft > 0)
...{
int recv = stream.Read(message, start, dataleft);
start += recv;
dataleft -= recv;
}
}
catch ...{ }
}
}
... {
Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
NetworkStream stream = new NetworkStream(socket);
while (true)
...{
try
...{
byte[] datasize = new byte[4];
stream.Read(datasize, 0, 4);
int size = BitConverter.ToInt32(datasize, 0);
byte[] message = new byte[size];
int dataleft = size;
int start = 0;
while (dataleft > 0)
...{
int recv = stream.Read(message, start, dataleft);
start += recv;
dataleft -= recv;
}
}
catch ...{ }
}
}
private
void
buttonSend_Click(
object
sender, System.EventArgs e)
... {
string str = this.richTextBoxSend.Rtf;
int i = str.Length;
if (i == 0)
...{
return;
}
else
...{
i *= 2;
}
byte[] datasize = new byte[4];
datasize = BitConverter.GetBytes(i);
byte[] sendbytes=Encoding.Unicode.GetBytes(str);
try
...{
NetworkStream netStream=new NetworkStream(clientSocket);
netStream.Wirte(datasize,0,4);
netStream.Write(sendbytes,0,sendbytes.Length);
netStream.Flush();
this.richTextBoxSend.Rtf="";
}
catch...{}
}
... {
string str = this.richTextBoxSend.Rtf;
int i = str.Length;
if (i == 0)
...{
return;
}
else
...{
i *= 2;
}
byte[] datasize = new byte[4];
datasize = BitConverter.GetBytes(i);
byte[] sendbytes=Encoding.Unicode.GetBytes(str);
try
...{
NetworkStream netStream=new NetworkStream(clientSocket);
netStream.Wirte(datasize,0,4);
netStream.Write(sendbytes,0,sendbytes.Length);
netStream.Flush();
this.richTextBoxSend.Rtf="";
}
catch...{}
}