- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我在我的主笔记本电脑和另一台笔记本电脑上安装了通用 TCP 客户端和 TCP 监听器。客户端和监听器是它们自己的独立程序,因此我在两台笔记本电脑上都运行了客户端和服务器,以尝试运行一个简单的即时消息程序。
如果两个程序都在同一台笔记本电脑上执行,客户端和服务器将愉快地通信。我的主笔记本电脑和其他笔记本电脑都是如此。
我的主笔记本电脑的客户端将愉快地向我的另一台笔记本电脑发送消息,而另一台笔记本电脑将优雅地接收来 self 的主笔记本电脑的消息 笔记本电脑。
但是,当我的另一台笔记本电脑的客户端向我的主笔记本电脑的服务器发送消息时,它会收到与超时相关的通信失败类型的错误。它只是不发送消息。
错误信息(被try-catch捕获);“连接尝试失败,因为连接方在一段时间后没有正确响应,或者建立的连接失败,因为连接的主机没有响应{我的 IP:端口号}。”
我得到的 IP 和端口号是正确的,所以排除这种情况。没有防火墙业务,因为另一台笔记本电脑根本不关心从我的主笔记本电脑接收消息。
我还尝试了随机端口号,并确保我的主笔记本电脑上的客户端连接到我的另一台笔记本电脑的服务器正在监听(或从中接收消息)的相同端口号。
那么为什么我的另一台笔记本电脑没有成功地向我的主笔记本电脑发送消息?
客户端要求用户输入 IP,然后输入端口号。然后等待用户输入消息,然后连接并通过给定的端口号将该消息发送到 IP。
服务器要求用户输入端口号并打印通过该端口接收到的消息。
这是客户端程序的代码;
static void Main(string[] args)
{
string IP = localIPAddress();
Console.WriteLine("Your IP: " + IP); //provides IP number
Console.Write("Enter IP to connect to: ");
string connectToIP = Console.ReadLine();
if (connectToIP == "self")
{
connectToIP = localIPAddress();
// if I want to test both on the same computer
}
Console.WriteLine("\nEnter port number: ");
int portNo = int.Parse(Console.ReadLine());
while (true)
{
string message = Console.ReadLine();
try
{
// connection doesn't begin until ReadLine is done
request(connectToIP, portNo, message);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
public static string localIPAddress()
{
IPHostEntry host;
string localIP = "?";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
localIP = ip.ToString();
}
}
return localIP;
}
static void request(string address, int port, string message)
{
TcpClient client = new TcpClient();
client.SendTimeout = 1000;
client.ReceiveTimeout = 1000;
try
{
client.Connect(address, port);
StreamWriter sw = new StreamWriter(client.GetStream());
sw.WriteLine(message);
sw.Flush();
sw.Close();
}
catch (Exception a)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine(a.Message.ToString());
Console.ResetColor();
}
}
这是服务器的代码;
static void Main(string[] args)
{
Console.WriteLine("Your IP: " + localIPAddress());
Console.Write("Enter port number you're receiving from: ");
int portNo = int.Parse(Console.ReadLine());
TcpListener listener = new TcpListener(IPAddress.Any, portNo);
Socket connection;
NetworkStream socketStream;
listener.Start();
while (true)
{
connection = listener.AcceptSocket();
connection.SendTimeout = 1000;
connection.ReceiveTimeout = 1000;
socketStream = new NetworkStream(connection);
try
{
respond(socketStream);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
socketStream.Close();
connection.Close();
}
}
}
public static string localIPAddress()
{
IPHostEntry host;
string localIP = "?";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
if (ip.AddressFamily == AddressFamily.InterNetwork)
{
localIP = ip.ToString();
}
}
return localIP;
}
static void respond(NetworkStream strm)
{
List<string> sentIn = new List<string>();
StreamReader sr = new StreamReader(strm);
while (sr.Peek() != -1)
sentIn.Add(sr.ReadLine());
sr.Close();
foreach (string s in sentIn)
{
Console.WriteLine(s);
}
}
我的代码有问题吗?当两台笔记本电脑使用这些程序时,都没有出现与防火墙相关的消息。
它可能是客户端的 sw.Flush(),因为它曾经导致发送过程卡住。
提前致谢。一旦我解决了这个问题,我就会开始想知道如何使用它来制作多人 XNA 游戏。
最佳答案
您可能想尝试将超时时间延长一点(或将它们全部删除;它们给我带来了问题)。此外,在主线程上处理发送时创建一个线程来接收消息确实是个好主意。
一些注意事项:
如果您想连接到您的本地 IP,您可以使用“loopback”或“127.0.0.1”
if (connectToIP == "self")
{
connectToIP = localIPAddress();
// if I want to test both on the same computer
}
你真的不应该连接,发送一条消息,然后断开连接,只是为了再次连接。
为客户尝试这样的事情:
using System.Threading;
static void Main(string[] args)
{
TcpClient client = new TcpClient();
Console.Write("IP: ");
string ip = Console.ReadLine();
Console.Write("Port: ");
int port = int.Parse(Console.ReadLine());
try
{
client.Connect(ip, port);
StreamWriter sw = new StreamWriter(client.GetStream());
sw.AutoFlush = true;
StreamReader sr = new StreamReader(client.GetStream());
Thread readThread = new Thread(() => readSocket(sr));
readThread.Start(); //Run readSocket() at the same time
string message = "";
while (message != "exit")
{
message = Console.ReadLine();
sw.WriteLine(message);
}
client.Close();
return;
}
catch (Exception e) { Console.WriteLine(e.ToString()); }
}
static void readSocket(StreamReader sr)
{
try
{
string message = "";
while ((message = sr.ReadLine()) != null)
{
Console.WriteLine(message);
}
}
catch (System.IO.IOException) { /*when we force close, this goes off, so ignore it*/ }
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
这是服务器的一个例子:
static void Main(string[] args)
{
Console.Write("Port: ");
int port = int.Parse(Console.ReadLine());
TcpListener server = new TcpListener(IPAddress.Any, port);
try
{
server.Start();
TcpClient client = server.AcceptTcpClient();
StreamWriter sw = new StreamWriter(client.GetStream());
sw.AutoFlush = true;
StreamReader sr = new StreamReader(client.GetStream());
Thread readThread = new Thread(() => readSocket(sr));
readThread.Start();
string message = "";
while (message != "exit")
{
message = Console.ReadLine();
sw.WriteLine(message);
}
client.Close();
return;
}
catch (Exception e) { Console.WriteLine(e.ToString()); }
}
static void readSocket(StreamReader sr)
{
try
{
string message = "";
while ((message = sr.ReadLine()) != null)
{
Console.WriteLine(message);
}
}
catch (System.IO.IOException) { /*when we force close, this goes off, so ignore it*/ }
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
这是一个异步服务器的代码,它向所有连接的客户端转发消息(如果您担心无法共享端口)。
我试图让这些示例保持简单,但为所有示例添加更多异常处理可能是个好主意。
class Server
{
private int port;
private Socket serverSocket;
private List<StateObject> clientList;
private const int DEFAULT_PORT = 1338;
public Server()
{
this.port = 1338; //default port
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientList = new List<StateObject>();
}
public Server(int port)
{
this.port = port;
serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientList = new List<StateObject>();
}
public void startListening(int port = DEFAULT_PORT)
{
this.port = port;
serverSocket.Bind(new IPEndPoint(IPAddress.Any, this.port));
serverSocket.Listen(1);
serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
private void AcceptCallback(IAsyncResult AR)
{
try
{
StateObject state = new StateObject();
state.workSocket = serverSocket.EndAccept(AR);
//Console.WriteLine("Client Connected");
clientList.Add(state);
state.workSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, SocketFlags.None, new AsyncCallback(ReceiveCallback), state);
serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), null);
}
catch { }
}
private void ReceiveCallback(IAsyncResult AR)
{
StateObject state = (StateObject)AR.AsyncState;
Socket s = state.workSocket;
try
{
int received = s.EndReceive(AR);
if (received == 0)
return;
if (received > 0)
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, received));
string content = state.sb.ToString();
if (content.IndexOf(Environment.NewLine) > -1)
{
//Console.WriteLine(content);
foreach (StateObject others in clientList)
if (others != state)
others.workSocket.Send(Encoding.ASCII.GetBytes(content.ToCharArray()));
state.sb.Clear();
}
Array.Clear(state.buffer, 0, StateObject.BufferSize);
s.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
catch (Exception huh) {
s.Close();
s.Dispose();
//Console.WriteLine("Client Disconnected");
clientList.Remove(state);
return;
}
}
class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 1024;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
}
}
关于C# TCP 聊天服务器 : Connection only works one way,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23390254/
我第一次决定切换到 InnoDB 并尝试使用外键和其他 InnoDB 功能。 创建关系时,我应该只在一张表上声明它们吗?还是两个表? 例如,对于以下每种情况,您将在何处以及如何声明关系? 1 用户有很
老方法 当我以前在需要内容被搜索引擎索引的项目中异步加载页面时,我使用了一种非常简单的技术,那就是 Page $('#example').click(function(){
我目前正在为自己创建自己的自定义应用程序来编译 Java 文件。我的应用程序可以完美地编译 Java 文件,但现在我想开始为 Java 文件添加某种类型的测试(例如,我将一些变量传递给许多不同的文件
我需要建立从我的 iPhone 应用程序到客户服务器的 HTTPS 双向 SSL 连接。但是我没有看到任何安全的方式来将客户端证书传递给应用程序(这是一个电子银行应用程序,所以安全性确实是一个问题)。
我从事 Java 工作已经很长时间了,大约 6 个月前开始使用 Scala。我喜欢这门语言。我发现的一件事是,做事有多种方法。我不知道这是因为该语言的性质,还是因为它还很年轻并且在不断发展,习惯用法和
这是我所指的示例代码。 https://sites.google.com/site/ssljavaguide/example-code/2-way-ssl 我是否可以不设置与 keystore 相关的
我读过有关使用 MySQL AES_ENCRYPT/AES_DECRYPT(双向加密)不如使用 PHP - hash()(单向加密)安全的信息。 http://bytes.com/topic/php/
我正在进行一个路线选择项目,我需要使用道路类型和单向/双向交通信息填充道路网络。我想知道Tiger/Line道路数据集是否包含这样的数据。。我下载了加利福尼亚州的Tiger/Line道路数据集,但没有
我需要开发一个 iPad 应用程序,它应该管理两种方向模式(横向和纵向)。 根据 official Apple iOS documentation , 有 2 种方法可以继续。 -第一个包括在收到旋转
我正在训练一个 randomForest 模型,目的是保存它以进行预测(它将被下载并在外部上下文中使用)。我希望这个模型尽可能最小。 我读到有很多options和 packages减少模型的内存大小。
为什么将参数传递给匿名函数会影响结果?例如,下面的脚本将 a1 显示为 function(),将 a2 显示为数组。 var a1=(function(){return [1*2,2*2,3*2];}
我有一个 Python 列表: listx = [["a", 127, "Blue", 0], ["b", 127, "Red", 1], ["b", 127, "
在查看 Java 库时,特别是构造函数,我注意到字段通常会出于某种原因进行初始化和验证: public java.awt.Color(int r, int g, int b, int a) {
我想编写 Git 脚本。只创建一个 Unix 脚本是最好的方法吗? #!/bin/bashgit push origin master &&git checkout develop &&git mer
这个问题在这里已经有了答案: class or method alias in java (8 个回答) 去年关闭。 我有一个类的名称可能不必要地繁琐,其中包含许多我在其他地方使用的静态方法。 而不是
这个问题在这里已经有了答案: Best way to check function arguments? [closed] (14 个回答) Parameter validation, Best pr
在阅读我遇到的代码时,结构的以下定义和初始化: // header file struct foo{ char* name; int value; }; //Implementation file s
我正在使用多页表单方法在 Drupal 中开发一个自定义模块,并且我希望对步骤进行可视化。 步骤 1 > [_Step_2_] > 步骤 3 > 完成 商业规则: 他们总是能看到所有的步骤,以及他们现
Josh 的 answer 给我留下了深刻的印象关于客户端的“Angular 方式”和声明式风格。 但是你能帮我理解一下,怎么做吗: 我有一个单页应用程序,左侧是菜单栏,右侧是 div 容器。 当用户
Subversion 商店正在考虑改用 Mercurial,试图提前弄清楚开发人员的所有提示将是什么。这里有一个相当常见的用例,我不知道如何处理。 我正在研究一些较大的功能,我有一个重要的代码部分——
我是一名优秀的程序员,十分优秀!