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

...{ }
}
}
}
以上是一个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 ...{ }
}
}
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...{}
}