其实以前也看过这个东西,不过当时人太菜了,没搞清楚...现在要好一点了,所以再做了一遍.
这回一共用了两种方法做,一种是用的Socket,
写了个类.其中方法有:string Listen(IPAddress ipAddress),void Send(EndPoint point, string message)
/// <summary>
/// 侦听指定端口传入的信息,并返回
/// </summary>
/// <param name="ipAddress">要侦听的Ip,传入null为侦听所有Ip</param>
/// <returns></returns>
public string Listen(IPAddress ipAddress)
{
EndPoint point;
if (ipAddress == null)
{
point = new IPEndPoint(IPAddress.Any, Port);
}
else
{
point = new IPEndPoint(ipAddress, Port);
}
Socket s = CreateSocket();
s.Bind(point);
s.Listen(0);
Socket temp = s.Accept();
this.Point = temp.LocalEndPoint;
s.Close();
string recvStr = "";
if (temp != null)
{
recvStr = Receive(temp);
temp.Close();
}
return recvStr;
}
/// <summary>
/// 发送信息
/// </summary>
/// <param name="address">接收端的Ip信息</param>
/// <param name="message">发送的内容</param>
public void Send(EndPoint point, string message)
{
Socket so = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
so.Connect(point);
byte[] bs = Encoding.UTF8.GetBytes(message);
so.Send(bs, bs.Length, SocketFlags.None);
so.Close();
}
#region 私有方法
/// <summary>
/// 接收侦听端口的信息
/// </summary>
/// <param name="temp"></param>
/// <returns></returns>
private string Receive(Socket temp)
{
byte[] recvBytes = new byte[1024];
int bytes;
bytes = temp.Receive(recvBytes, recvBytes.Length, SocketFlags.None);
return Encoding.UTF8.GetString(recvBytes, 0, bytes);
}
/// <summary>
/// 创建一个Socket
/// </summary>
/// <returns></returns>
private Socket CreateSocket()
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
return socket;
}
#endregion
这样,在服务端启动的时候,启动一个线程.调用下面这个方法:
private void GetValues()
{
MySocket mySocket = new MySocket();
string va = mySocket.Listen(null);
SetValue(va);
thmain = new Thread(GetValues);
thmain.Start();
}
private void SetValue(string values)
{
if (listBox1.InvokeRequired)
{
listDelete li = new listDelete(SetValue);
this.Invoke(li, new object[] { values });
}
else
{
//string v = string.Empty;
if (values.StartsWith("@Ip"))
{
values = values.Replace("@Ip", "");
listBox2.Items.Add(values);
}
else
{
listBox1.Items.Add(values);
listBox1.SelectedIndex = listBox1.Items.Count - 1;
}
}
}
这样,在服务端就一直侦听,当然是通过线程来完成的,不然会卡起不动,用到线程的话就会产生线程间操作控件的问题,SetValue就是解决它的.
客户端加载时,调用.Send(serverIp, "@Ip" + Dns.GetHostAddresses(Dns.GetHostName())[0].ToString());,向服务器发送一个本机的IP,同时,调用侦听方法..一直侦听,.发送的话就调用发送方法.
不过这里运行后产生了个问题,在运行的时候,当服务端侦听后.客户端就不能侦听了.异常信息是不能同时绑定一个端口.
后来换了个实现方法:
只是改了类中的两个方法而已,.
public string Listen(string ip)
{
TcpListener tcpLis = new TcpListener(IPAddress.Any, 8000);
tcpLis.Start();
TcpClient client = tcpLis.AcceptTcpClient();
NetworkStream nsStream = client.GetStream();
StreamReader srRead = new StreamReader(nsStream);
string va = srRead.ReadLine();
tcpLis.Stop();
client.Close();
nsStream.Close();
srRead.Close();
return va;
}
public void Send(string ip, string message)
{
TcpClient tcpClient = new TcpClient(Dns.GetHostEntry(IPAddress.Parse(ip)).HostName, 8000);
NetworkStream nsStream = tcpClient.GetStream();
StreamWriter swWriter = new StreamWriter(nsStream);
swWriter.WriteLine(message);
swWriter.Flush();
tcpClient.Close();
nsStream.Close();
swWriter.Close();
}
这样做出来就完全可以了,,客户端和服务端都可能收发信息,像QQ一样,
就写到这里,,今天很累//