目前自动进行ip配置的想法:
1首先serve和客户端都使用DHCP自动分配地址。
2.serve使用udp广播自己的ip,客户端监听serve的广播,拿到服务器地址后配置tcp的设置。
3.socket进行tcp通信,
这样在局域网内可以不用手动设置serve的地址。
private string localIP ="";
<2>serve的udp代码:
private void Broadcast()
{
localIP = Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(p => p.AddressFamily.ToString() == "InterNetwork").ToString();
UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
IPEndPoint endPoint = new IPEndPoint(IPAddress.Broadcast, 1234);
byte[] buf = Encoding.UTF8.GetBytes(localIP);
client.Send(buf, buf.Length, endPoint);
}
客户端代码:.
private void udpReceive()
{
IPEndPoint localEP = new IPEndPoint(IPAddress.Any, 1234);
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
UdpClient udpClient = new UdpClient(localEP);
byte[] data = udpClient.Receive(ref remoteEP);
string msg = Encoding.UTF8.GetString(data, 0, data.Length);
Console.WriteLine(msg);
}
tcp部分:
服务器端:
using System;
using System.Net;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Collections.Generic;
class Program
{
public static List<Socket> sockets = new List<Socket>();//客户端池子
static void Main(string[] args)
{
IPEndPoint localEP = new IPEndPoint(IPAddress.Any, 1234);//定义侦听端口
Socket serve = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//定义套接字类型
try
{
serve.Bind(localEP); //连接
serve.Listen(10); //开始侦听
Console.WriteLine("Waiting for a client");//控制台输出侦听状态
while (true)
{
Socket sc = serve.Accept();//一旦接受连接,创建一个客户端
sockets.Add(sc);
Thread t = new Thread(new ThreadStart(() => ReceiveMsg(sc)));//开启当前Socket线程, 去执行获取数据的动作,与客户端通信
t.IsBackground = true;
t.Start();
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
public static void ReceiveMsg(Socket sc)
{
byte[] buffer = new byte[1024];
Console.WriteLine("客户端:" + sc.RemoteEndPoint.ToString());
buffer = Encoding.ASCII.GetBytes("Connect successful!");//数据类型转换
sc.Send(buffer, buffer.Length, SocketFlags.None); //发送
while (true)
{
try
{
buffer = new byte[1024]; //对buffer清零
int recv = sc.Receive(buffer);//recv真实数据长度 ******* length是声明变量的长度
if (recv == 0)
{
break;
}
Console.WriteLine(((IPEndPoint)sc.RemoteEndPoint).Address + ":" + Encoding.UTF8.GetString(buffer, 0, recv)); //输出接收到的数据
sc.Send(buffer, recv, SocketFlags.None);//将接收到的数据再发送出去
}
catch (Exception e)
{
Console.WriteLine(((IPEndPoint)sc.RemoteEndPoint).Address + "------下线");
break;
}
}
sc.Close();
sockets.Remove(sc);//如果接收的过程中,断开, 那么移除当前Socket对象, 并且退出当前线程
}
public static void BroadcastALL(string msg, params object[] parm)
{
byte[] buffer = Encoding.UTF8.GetBytes("对已连接的客户端进行广播");//可以替换使用msg。
foreach (var item in sockets)
{
item.Send(buffer, buffer.Length, SocketFlags.None);
}
}
}
客户端:
using System;
using System.Net;
using System.Text;
using System.Net.Sockets;
class Program
{
static void Main(string[] args)
{
byte[] buffer = new byte[1024]; //定义发送数据缓存
string input, stringData; //定义字符串,用于控制台输出或输入
IPEndPoint serveEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 1234);
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //定义套接字类型
try
{
socket.Connect(serveEP); //尝试连接
}
catch (SocketException e)
{
Console.Write("Fail to connect server" + e.ToString());
return;
}
int recv = socket.Receive(buffer);//recv真实数据长度 ******* length是声明变量的长度
stringData = Encoding.UTF8.GetString(buffer, 0, recv); //将接收的数据转换成字符串
Console.WriteLine(stringData);
Console.WriteLine("Input your message:");
input = Console.ReadLine();
while (input != "exit")
{
buffer = Encoding.UTF8.GetBytes(input);//将从键盘获取的字符串转换成整型数据并存储在数组中
socket.Send(buffer, buffer.Length, SocketFlags.None); //发送
buffer = new byte[1024];//对buffer清零
recv = socket.Receive(buffer); //接收到的数据的长度
stringData = Encoding.UTF8.GetString(buffer, 0, recv);//将接收到的数据转换为字符串
Console.WriteLine("Recive: " + stringData);//控制台输出字符串
input = Console.ReadLine();
}
Console.Write("disconnect from server");
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
}
websocket 部分:
1.服务器:需要WebSocketSharp.dll Json.dll(.net 3.5)
using Json;
using System;
using WebSocketSharp;
using WebSocketSharp.Server;
using System.Collections.Generic;
public class Chat : WebSocketBehavior
{
private Dictionary<string, string> userList = new Dictionary<string, string>();
protected override void OnMessage(MessageEventArgs e)
{
try
{
var obj = JsonParser.Deserialize<JsonDto>(e.Data);
Console.WriteLine("收到消息:" + obj.content + " 类型:" + obj.type + " id:" + ID + " name:" + userList[ID]);
switch (obj.type)
{
case "1":
obj.name = userList[ID];
Sessions.Broadcast(JsonParser.Serialize(obj));
break;
case "2":
Console.WriteLine("{0}修改名称{1}", userList[ID], obj.content);
Broadcast(string.Format("{0}修改名称{1}", userList[ID], obj.content), "3");
userList[ID] = obj.content;
break;
default:
Sessions.Broadcast(e.Data);
break;
}
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
}
protected override void OnClose(CloseEventArgs e)
{
Console.WriteLine("连接关闭" + ID);
Broadcast(string.Format("{0}下线,共有{1}人在线", userList[ID], Sessions.Count), "3");
userList.Remove(ID);
}
protected override void OnError(ErrorEventArgs e)
{
Console.WriteLine(e.Exception);
}
protected override void OnOpen()
{
Console.WriteLine("建立连接" + ID);
userList.Add(ID, "游客" + Sessions.Count);
Broadcast(string.Format("{0}上线了,共有{1}人在线", userList[ID], Sessions.Count), "3");
}
private void Broadcast(string msg, string type = "1")
{
var data = new JsonDto() {
content = msg, type = type, name = userList[ID] };
Sessions.Broadcast(JsonParser.Serialize(data));
}
}
using System;
using System.Net;
using WebSocketSharp.Server;
class Program
{
static void Main(string[] args)
{
var serve = new WebSocketServer(IPAddress.Parse("127.0.0.1"), 1234);
serve.AddWebSocketService<Chat>("/Chat");
serve.Start();
Console.ReadKey(true);
serve.Stop();
}
}
class JsonDto
{
public string content {
get; set; }
public string type {
get; set; }
public string name {
get; set; }
}
2.C#客户端:需要WebSocketSharp.dll Json.dll
using System;
using WebSocketSharp;
class Program
{
static void Main(string[] args)
{
WebSocket ws = new WebSocket("ws://127.0.0.1:1234/Chat");
ws.OnMessage += (sender, e) =>
{
JsonDto jd = Json.JsonParser.Deserialize<JsonDto>(e.Data);
Console.WriteLine("Received: " + jd.name + " : " + jd.content);
};
ws.Connect();
Console.WriteLine("Client is ready.1:send message,2:rename");
string str = Console.ReadLine();
while (str != "exit")
{
if (str == "1")
{
JsonDto jsonDto = new JsonDto
{
content = "hello word,好啊",
type = "1"
};
str = Json.JsonParser.Serialize<JsonDto>(jsonDto);
ws.Send(str);
}
else if (str == "2")
{
JsonDto jsonDto = new JsonDto
{
content = "wang",
type = "2"
};
str = Json.JsonParser.Serialize<JsonDto>(jsonDto);
ws.Send(str);
}
str = Console.ReadLine();
}
Console.ReadLine();
}
}
class JsonDto
{
public string content {
get; set; }
public string type {
get; set; }
public string name {
get; set; }
}
3.web端客户端:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<textarea id="textarea" style="height: 500px; width: 300px;"></textarea>
<div>
<input type="text" id="message">
<input type="button" id="send" onclick="send()" value="发送">
<input type="text" id="nameText">
<input type="button" id="name" onclick="reName()" value="改名">
</div>
<script type="text/javascript">
//检查浏览器是否支持WebSocket
if (!window.WebSocket) {
console.log('您的浏览器不支持WebSocket,请选择其他的浏览器再尝试连接服务器');
}
var el = document.getElementById("textarea");
var wsClient = new WebSocket('ws://127.0.0.1:1234/Chat');
wsClient.open = function (e) {
el.value += "连接成功!\r\n";
}
wsClient.onclose = function (e) {
el.value += "连接断开!\r\n";
}
wsClient.onmessage = function (e) {
let res=JSON.parse(e.data);
el.value += "接收消息:" + res.name+" : "+res.content+ "\r\n";
}
wsClient.onerror = function (e) {
el.value += "连接失败!原因【" + e.data + "】\r\n";
}
function send() {
let contents = document.getElementById("message");
wsClient.send( JSON.stringify({
'type':'1','content':contents.value}));
}
function reName() {
let contents = document.getElementById("nameText");
wsClient.send( JSON.stringify({
'type':'2','content':contents.value}));
}
</script>
</body>
</html>