客户端-服务器网络入门[关闭]

2023-11-24

我是一名优秀的程序员,但我的网络经验为零。

基本上,我想进入客户端服务器网络。例如,我想尝试启动一个服务器进程,该进程允许客户端通过互联网连接并向所有其他连接的客户端发送 ping。然后也许我会尝试开发一个简单的聊天客户端,或者一些简单的多人游戏,然后我会从那里开始。

我非常了解可能有用的语言:Java、C++、C。

我该如何开始?我想预先学习最佳实践,因此您可以推荐的良好学习资源(例如书籍、在线材料等)会很棒。

编辑:我还应该研究某种虚拟机来模拟各种机器之间的交互吗?

编辑 2:我已经设置了 50 次代表的赏金。到目前为止已经提出了一些很好的答案 - 不过我正在寻找更详细的答案,所以希望这会鼓励我。例如,具有此类经验的人比较不同学习方法的答案将非常有帮助。谢谢!我还可以获得有关整个虚拟机问题的一些反馈吗?


我更喜欢Java。我来解释一下TCP:
基本概念是您必须在计算机上运行“服务器”。该服务器接受等待连接的客户端。每个连接都经过一个端口(你知道,我希望......)。
始终使用高于 1024 的端口,因为低于 1025 的端口大部分时间是为标准协议保留的(例如 HTTP (80)、FTP (21)、Telnet...)

然而,在 Java 中创建服务器是这样完成的:

ServerSocket server = new ServerSocket(8888); // 8888 is the port the server will listen on.

如果您想进行研究,“套接字”可能是您正在寻找的词。
要将客户端连接到服务器,您必须编写以下内容:

Socket connectionToTheServer = new Socket("localhost", 8888); // First param: server-address, Second: the port

但现在,仍然没有联系。服务器必须接受等待的客户端(正如我在上面注意到的):

Socket connectionToTheClient = server.accept();

完毕!您的连接已建立!通信就像文件 IO。您唯一需要记住的是,您必须决定何时要刷新缓冲区并真正通过套接字发送数据。
使用 PrintStream 进行文本写入非常方便:

OutputStream out = yourSocketHere.getOutputStream();
PrintStream ps = new PrintStream(out, true); // Second param: auto-flush on write = true
ps.println("Hello, Other side of the connection!");
// Now, you don't have to flush it, because of the auto-flush flag we turned on.

用于文本阅读的 BufferedReader 是很好的(最好的*)选择:

InputStream in = yourSocketHere.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line = br.readLine();
System.out.println(line); // Prints "Hello, Other side of the connection!", in this example (if this would be the other side of the connection.

希望您可以利用这些信息开始建立网络!
PS:当然,所有网络代码都必须对 IOExceptions 进行 try-catch。

EDIT:我忘了写为什么它并不总是最好的选择。 BufferedReader 使用缓冲区并尽可能多地读取缓冲区。但有时您不希望 BufferedReader 窃取换行符后的字节并将它们放入自己的缓冲区中。
简短的例子:

InputStream in = socket.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
// The other side says hello:
String text = br.readLine();
// For whatever reason, you want to read one single byte from the stream,
// That single byte, just after the newline:
byte b = (byte) in.read();

但是 BufferedReader 的缓冲区中已经有了您想要读取的字节。所以打电话in.read()将返回读取器缓冲区中最后一个字节后面的字节。

因此,在这种情况下,最好的解决方案是使用DataInputStream并以您自己的方式管理它,以了解字符串的长度,并仅读取该字节数并将它们转换为字符串。或者:你使用


DataInputStream.readLine()  

此方法不使用缓冲区,而是逐字节读取并检查换行符。所以这个方法不会从底层的InputStream中窃取字节。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

客户端-服务器网络入门[关闭] 的相关文章

  • 总是使用 Final?

    我读过 将某些东西做成最终的 然后在循环中使用它会带来更好的性能 但这对一切都有好处吗 我有很多地方没有循环 但我将 Final 添加到局部变量中 它会使速度变慢还是仍然很好 还有一些地方我有一个全局变量final 例如android Pa
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 使用 Bearer Token 访问 IdentityServer4 上受保护的 API

    我试图寻找此问题的解决方案 但尚未找到正确的搜索文本 我的问题是 如何配置我的 IdentityServer 以便它也可以接受 授权带有 BearerTokens 的 Api 请求 我已经配置并运行了 IdentityServer4 我还在
  • Eclipse Java 远程调试器通过 VPN 速度极慢

    我有时被迫离开办公室工作 这意味着我需要通过 VPN 进入我的实验室 我注意到在这种情况下使用 Eclipse 进行远程调试速度非常慢 速度慢到调试器需要 5 7 分钟才能连接到远程 jvm 连接后 每次单步执行断点 行可能需要 20 30
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • Google App Engine 如何预编译 Java?

    App Engine 对应用程序的 Java 字节码使用 预编译 过程 以增强应用程序在 Java 运行时环境中的性能 预编译代码的功能与原始字节码相同 有没有详细的信息这是做什么的 我在一个中找到了这个谷歌群组消息 http groups
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • 对现有视频添加水印

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • 向现有 TCP 和 UDP 代码添加 SSL 支持?

    这是我的问题 现在我有一个 Linux 服务器应用程序 使用 C gcc 编写 它与 Windows C 客户端应用程序 Visual Studio 9 Qt 4 5 进行通信 是什么very在不完全破坏现有协议的情况下向双方添加 SSL
  • 获取 JVM 上所有引导类的列表?

    有一种方法叫做findBootstrapClass对于一个类加载器 如果它是引导的 则返回一个类 有没有办法找到类已经加载了 您可以尝试首先通过例如获取引导类加载器呼叫 ClassLoader bootstrapLoader ClassLo
  • 为什么编译时浮点计算可能不会得到与运行时计算相同的结果?

    In the speaker mentioned Compile time floating point calculations might not have the same results as runtime calculation
  • 通过指向其基址的指针删除 POD 对象是否安全?

    事实上 我正在考虑那些微不足道的可破坏物体 而不仅仅是POD http en wikipedia org wiki Plain old data structure 我不确定 POD 是否可以有基类 当我读到这个解释时is triviall
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • 捕获的图像分辨率太大

    我在做什么 我允许用户捕获图像 将其存储到 SD 卡中并上传到服务器 但捕获图像的分辨率为宽度 4608 像素和高度 2592 像素 现在我想要什么 如何在不影响质量的情况下获得小分辨率图像 例如我可以获取或设置捕获的图像分辨率为原始图像分
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j

随机推荐