我正在为在线游戏编写服务器,最终应该能够处理1,000-2,000个客户端.我发现这样做的3种方法基本上是:
在过去,我使用过1,但众所周知,它不能很好地扩展.2是可以的,但我有一种复杂的感觉,关于一个客户在技术上能够让其他人冻结.3听起来很有趣(比2好一点),但我听说它不适合太多连接.那么,最好的方法是什么(在D中)?还有其他选择吗?
在我当前的项目中,我必须解析一个字符串,并将其中的一部分写入控制台.在测试如何在没有太多开销的情况下执行此操作时,我发现我测试的一种方法实际上比Console.WriteLine更快,这对我来说有点困惑.
我知道这是不是该到基准东西有道,但我通常用粗糙的"这是比这个更快",这是我可以运行了几次后告诉罚款.
static void Main(string[] args)
{
var timer = new Stopwatch();
timer.Restart();
Test1("just a little test string.");
timer.Stop();
Console.WriteLine(timer.Elapsed);
timer.Restart();
Test2("just a little test string.");
timer.Stop();
Console.WriteLine(timer.Elapsed);
timer.Restart();
Test3("just a little test string.");
timer.Stop();
Console.WriteLine(timer.Elapsed);
}
static void Test1(string str)
{
Console.WriteLine(str);
}
static void Test2(string str)
{
foreach (var c in str)
Console.Write(c);
Console.Write('\n');
}
static void Test3(string str)
{
using (var stream = new StreamWriter(Console.OpenStandardOutput()))
{
foreach (var c in str)
stream.Write(c);
stream.Write('\n');
}
} …Run Code Online (Sandbox Code Playgroud) 一段时间以来,我一直在我的各种程序中使用以下函数围绕枢轴点旋转一系列点。
\n\nprivate Point RotatePoint(Point point, Point pivot, double radians)\n{\n var cosTheta = Math.Cos(radians);\n var sinTheta = Math.Sin(radians);\n\n var x = (cosTheta * (point.X - pivot.X) - sinTheta * (point.Y - pivot.Y) + pivot.X);\n var y = (sinTheta * (point.X - pivot.X) + cosTheta * (point.Y - pivot.Y) + pivot.Y);\n\n return new Point((int)x, (int)y);\n}\nRun Code Online (Sandbox Code Playgroud)\n\n这一直很有效,直到我尝试反复少量旋转形状。例如,这是我在由 4 个点组成的矩形多边形上调用 45\xc2\xb0 得到的结果:
\n\nforeach (var point in points)\n Rotate(point, center, Math.PI / 180f * 45);\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n但这是我通过对 1\xc2\xb0 调用旋转 45 次得到的结果: …
我有一个Lua脚本,我正在尝试使用十六进制数字(0x ..).如果我在控制台中使用官方Windows二进制文件运行此脚本,它可以正常工作.但如果我在我的应用程序(简单dofile)中运行它,我会得到
malformed number near '0x1F'
Run Code Online (Sandbox Code Playgroud)
十六进制是什么并不重要,我总是得到那个错误,就像它不支持它们一样.我正在使用的库是Lua 5.1.4,我尝试了两个不同的库(第一个是我自己编译的那个),所以这应该不是问题.
有没有人知道这里可能有什么问题?
编辑: 这不是剧本.无论我做什么,简单的"foo = 0xf"都会触发错误,即使文件中没有其他内容也是如此.
更新:
tonumber("0xf")
Run Code Online (Sandbox Code Playgroud)
这会返回nil,而
tonumber("15")
Run Code Online (Sandbox Code Playgroud)
工作得很好.在我的库中,十六进制肯定有问题......
这不是关于如何做到这一点的问题,而是一个关于我正在做的事情是否错误的问题.我已经读过,在等待数据(BeginReceive)的同时,无法检测套接字是否意外关闭(如杀死服务器/客户端进程,拉动网络电缆),而不使用定时器或常规发送的消息等.但是很长一段时间我一直在使用以下设置来做到这一点,到目前为止它一直都很完美.
public void OnReceive(IAsyncResult result)
{
try
{
var bytesReceived = this.Socket.EndReceive(result);
if (bytesReceived <= 0)
{
// normal disconnect
return;
}
// ...
this.Socket.BeginReceive...;
}
catch // SocketException
{
// abnormal disconnect
}
}
Run Code Online (Sandbox Code Playgroud)
现在,既然我已经读过它并不容易,我想知道我的方法是否有问题.在那儿?或者杀戮过程和牵引电缆之间有什么区别?
我试图在我的第一个.lua文件中覆盖变量,在我的代码末尾要求第二个.
file1.lua
val = 1
require "file2"
Run Code Online (Sandbox Code Playgroud)
file2.lua
val = 2
Run Code Online (Sandbox Code Playgroud)
不幸的是,这似乎不起作用,因为val在此之后仍然是1.我提出的解决方案,允许这些文件的潜在未来用户包含文件,是一个新功能,我现在在初始化Lua时插入:
function include(file)
dofile("path/since_dofile_doesnt_seem_to_use/package/path" .. file .. ".lua")
end
Run Code Online (Sandbox Code Playgroud)
这完全符合预期,但由于我还是Lua的新手,我想知道,如果有更好的解决方案.也许已经有了一些东西?
更新:
我的问题是我在多个文件上多次意外地需要file2,并且Lua不会再次加载它来更改值.解决了.
我有一个XY类型,有各种领域和方法(几十个).
type XY struct {
Name string
SomeValue int
...
}
func (xy *XY) Do1() { ... }
func (xy *XY) Do2() { ... }
func (xy *XY) Do3() { ... }
...
Run Code Online (Sandbox Code Playgroud)
现在我想定义一个嵌入XY的第二种类型,保留所有字段和方法.但我确实想修改一些功能.
type AB struct {
XY
}
func (ab *AB) Do2() { ... }
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.现在我想将AB传递给一个带XY的函数.
func SomeFunc(xy *XY) { ... }
Run Code Online (Sandbox Code Playgroud)
而这里是我绊倒的地方,没有多态性.
我可以传递*AB.XY给函数,但不再使用AB的Do2函数了.我可以为它创建一个接口,这可能是预期的方式,但如果SomeFunc需要接近XY的所有函数,比如几乎所有字段的getter,我基本上需要创建一个XY的副本,作为一个接口(可能的用例:我在服务器上,必须以特定方式向客户端发送值).我不想只使它成为一个接口,因为我必须重新定义所有使用该接口的类型的所有字段和函数.
我可以想到这个问题的解决方案,例如将Do2设置为闭包,根据"主机"类型设置,或者设置XY中的枚举字段,并根据该"类型"变量更改Do2的行为,或者使用反射和interface{}在SomeFunc中,但我想知道Go中的"正确"方式是什么.即使你有很多功能,你如何以最有效的方式做到这一点?
我目前正在研究C#Generics,我有几个问题.
1)在下面的代码中,"Test"中T类型的比较是否会减慢程序?在其他语言中,这是在编译时处理的,但我不知道C#.
2)由于sizeof显然不起作用,我必须使用System.Runtime.InteropServices.Marshal.SizeOf.它是否正确?
3)我还没有在C#中看到这样的代码,它有什么不对,还是我在这里做的很好?最后,此示例中的方法将采用少数类型,如果无法处理它,则抛出异常.某些类型将被独立处理,其他类似short/int/long将根据其大小一起处理.
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Test<int>();
Test<long>();
Test<string>();
Console.ReadLine();
}
static void Test<T>()
{
Type type = typeof(T);
if (type == typeof(int) || type == typeof(long))
{
Console.WriteLine("int");
Console.WriteLine(System.Runtime.InteropServices.Marshal.SizeOf(type).ToString());
}
else if (type == typeof(string))
{
Console.WriteLine("string");
}
}
}
}
Run Code Online (Sandbox Code Playgroud) 最近有人告诉我,Class 1形式的循环引用如何称为Class 2,称为Class 1被认为是非常糟糕的做法,而我无法理解这一点.我的意思是,如果这些课程在2个不同的项目中,我完全理解这个问题,但如果他们在同一个项目中,那可能会很糟糕吗?在某些情况下......你究竟是怎么防止这种情况的?
例如:我有一台某种服务器.客户端连接到它,客户端从套接字派生或持有它,负责网络内容,以及一些信息,如帐户ID等.当有新的东西时,客户端调用数据包处理程序,现在数据包处理程序需要来自客户端的信息,并且必须返回信息.我将客户端传递给数据包处理程序,因此它可以调用它的发送函数等.
关注这个问题的人认为这是上面提到的不良做法,尽管我很少看到服务器,尤其是大型服务器,他们将所有数据包处理保留在客户端类中.此外,您可能会比处理程序更进一步,并调用更多类.将所有内容保留在客户端内是一团糟.所以... 这是非常糟糕的做法吗?
如果是的话,怎么会绕过它呢?要完成这项工作,您需要在客户端中使用或多或少复杂的对象集合,您可以向下传递,而无需再次调用客户端的功能...
就像我说的那样,我无法真正地围绕这个"问题".有人可以帮我吗?
我想将一个 C# 对象的引用放入非托管内存 (C),我猜是一个指针 (int),当 C 代码稍后回调到 C# 时,我想从非托管内存中取回引用,所以我可以解决它,并访问该对象。原因是 C 代码控制应该使用哪个对象,没有真正的替代方案。我对 C 代码的控制有限,不能选择 C++/CLI。
问题:这是否可能且安全,如果是,如何?