我试图在 C# 中进行一些测试,但它似乎不起作用,老实说我不明白为什么。 实验是这样的。我在列表中写了一些字符串,然后启动了两个线程:T1 是发送者,T2 是接收者。 T1读取我之前插入的字符串,然后通过T2读取的StreamWriter发送。在该过程结束时,T2 返回它读取的内容,程序终止。 T1 似乎工作正常:它发送数据,然后关闭连接。 T2好像收到了连接,但是没有读取:第一次读取总是null。
有人可以帮助我吗?
这是我的代码:
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using Windows.Foundation;
using Windows.Storage;
using System.Threading;
using System.Threading.Tasks;
using Windows.Storage.Streams;
using Windows.Networking;
using Windows.Networking.Sockets;
namespace UWPConsoleApp
{
class UWPConsoleApp
{
static void Main(string[] args)
{
List<String> toSend = new List<string>();
bool end = false;
do
{
Console.WriteLine("Please write something to send to the other task (write ';;;' to end)");
string s = Console.ReadLine();
if (s != ";;;")
{
toSend.Add(s);
Console.WriteLine($"The list now contains {toSend.Count} lines");
}
else
{
if(toSend.Count == 0)
{
Console.WriteLine("WARNING: you may insert atleast one line before going on");
continue;
}
end = true;
}
}
while (!end);
List<string> received;
Task[] tasks =
{
Task.Factory.StartNew( () =>
{
ThreadSender ts = new ThreadSender();
ts.buffer = toSend;
Console.WriteLine("(T1) waiting before starting...");
Thread.Sleep(7500);
ts.SendInfos();
} ),
Task.Factory.StartNew( async () =>
{
ThreadReceiver tr = new ThreadReceiver();
received = await tr.ReceiveInfos();
} )
};
Task.WaitAll(tasks);
Console.WriteLine("Done.");
Console.ReadKey();
}
}
class ThreadSender
{
// buffer di invio
public List<String> buffer;
// socket per l'invio dei dati
private StreamSocket ss;
public ThreadSender()
{
buffer = new List<string>();
ss = new StreamSocket();
}
public async void SendInfos()
{
HostName hn = new HostName("localhost");
await ss.ConnectAsync(hn, "3000");
StreamWriter sw = new StreamWriter(ss.OutputStream.AsStreamForWrite());
StreamReader sr = new StreamReader(ss.InputStream.AsStreamForRead());
Console.WriteLine($"(T1) Sending line count: {buffer.Count}");
sw.WriteLine(buffer.Count.ToString());
foreach(string line in buffer)
{
Console.WriteLine("(T1) sending line: {0}", line);
sw.WriteLine(line);
}
Thread.Sleep(5000);
Console.WriteLine("(T1) closing connection");
ss.Dispose();
ss = null;
}
}
class ThreadReceiver
{
// buffer di scrittura
public List<String> buffer = new List<string>();
private StreamSocketListener ssl;
private bool received = false;
private bool error = false;
public ThreadReceiver()
{
ssl = new StreamSocketListener();
}
public async Task<List<string>> ReceiveInfos()
{
ssl.ConnectionReceived += onConnectionReceived;
await ssl.BindServiceNameAsync("3000");
Console.WriteLine("(T2) waiting for connections...");
while (!received)
{
if(error)
{
Console.WriteLine("(T2) closing connection (error occurred)");
return null;
}
Thread.Sleep(2500);
}
return buffer;
}
public async void onConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
Console.WriteLine("received a incoming connection");
Thread.Sleep(2500);
StreamReader sr = new StreamReader(args.Socket.InputStream.AsStreamForRead());
string receivedCountString = await sr.ReadLineAsync();
if(receivedCountString == null)
{
Console.Error.WriteLine("(T2) ERROR: received null value");
error = true;
return;
}
int nToRead = Int32.Parse(receivedCountString);
while(nToRead > 0)
{
string receivedString = await sr.ReadLineAsync();
if (receivedString == null)
{
Console.Error.WriteLine("(T2) ERROR: received null value");
error = true;
return;
}
buffer.Add(receivedString);
nToRead--;
}
received = true;
}
}
}
以下是上述程序的输出示例:
Please write something to send to the other task (write ';;;' to end)
aaa
The list now contains 1 lines
Please write something to send to the other task (write ';;;' to end)
bbb
The list now contains 2 lines
Please write something to send to the other task (write ';;;' to end)
ccc
The list now contains 3 lines
Please write something to send to the other task (write ';;;' to end)
ddd
The list now contains 4 lines
Please write something to send to the other task (write ';;;' to end)
;;;
(T1) waiting before starting...
(T2) waiting for connections...
received a incoming connection
(T1) Sending line count: 4
(T1) sending line: aaa
(T1) sending line: bbb
(T1) sending line: ccc
(T1) sending line: ddd
(T1) closing connection
(T2) ERROR: received null value
(T2) closing connection (error occurred)
Done.
我正在使用 Windows11 和 Visual Studio 2019 来运行代码(UWP 项目)。
我看到其他类似的帖子找到了答案。特别是我找到了这个资源,它与我目前正在尝试做的事情有关。
我尝试在 VS2019 中使用 C# 在我的本地 PC 上构建一个客户端,并在我的 Linux 服务器计算机(我正在使用 ADA Cloud)上用 Python 构建一个服务器。这在第一次都不起作用:服务器卡住了等待一条消息...... C# 端应该已经发送了。
这是我的服务器:
#!/bin/bash
import socket
import sys
if len(sys.argv) < 2:
print("USAGE:\n\tserver.py <PORT_NO>")
sys.exit(1)
HOST = socket.gethostname()
print( f"Hostname is {HOST}" )
PORTNO = int(sys.argv[1])
print( f"port set to {PORTNO}" )
print("opening socket connection...")
sk = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
print( f"trying to open server using \n\tHOST {HOST} \n\tPORTNO {PORTNO}" )
sk.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sk.bind( (HOST, PORTNO) )
sk.listen( 4 )
print("OK - listening")
print( "waiting connection..." )
new_socket, new_socket_addr = sk.accept( )
print( "Conenction received!" )
print("waiting for messages...")
data = new_socket.recv(1024)
print( f"received:\n\t{data}" )
new_socket.send(data)
print("Echo done")
new_socket.close()
sk.close()
print("closing...")
这是我的客户:
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using Windows;
using Windows.Networking;
using Windows.Networking.Sockets;
namespace UWPConsoleApp
{
class UWPConsoleApp
{
static void Main(string[] argv)
{
string Host = "131.175.205.146";
string Portno = "5000";
Console.WriteLine("Trying to connect...");
StreamSocket ss = new StreamSocket();
ss.ConnectAsync(new HostName(Host), Portno).AsTask().GetAwaiter().GetResult();
Console.WriteLine($"Connection Estalished with HOST {Host} PORTNO {Portno}");
Console.WriteLine("Sending data...");
StreamWriter sw = new StreamWriter(ss.OutputStream.AsStreamForWrite());
sw.Write("asdiaiHNIUNAHidsi uh aiudnhai i ish i");
Console.WriteLine("Receiving data...");
StreamReader sr = new StreamReader(ss.InputStream.AsStreamForRead());
sr.ReadToEnd();
Console.WriteLine("OK! Closing...");
sr.Dispose();
sw.Dispose();
ss.Dispose();
}
}
}
我注意到每次调用 Write() 时,该网站中的代码片段都会启动 Flush()。好吧,我试过了……而且成功了!
// before
sw.Write("asdiaiHNIUNAHidsi uh aiudnhai i ish i");
// after
sw.Write("asdiaiHNIUNAHidsi uh aiudnhai i ish i");
sw.Flush();
嗯……我试过用这种方式更新上面的代码,然后……哦!它奏效了。
这是代码的最终版本:
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using Windows.Foundation;
using Windows.Storage;
using System.Threading;
using System.Threading.Tasks;
using Windows.Storage.Streams;
using Windows.Networking;
using Windows.Networking.Sockets;
namespace UWPConsoleApp
{
class UWPConsoleApp
{
static void Main(string[] args)
{
List<String> toSend = new List<string>();
bool end = false;
do
{
Console.WriteLine("Please write something to send to the other task (write ';;;' to end)");
string s = Console.ReadLine();
if (s != ";;;")
{
toSend.Add(s);
Console.WriteLine($"The list now contains {toSend.Count} lines");
}
else
{
if (toSend.Count == 0)
{
Console.WriteLine("WARNING: you may insert atleast one line before going on");
continue;
}
end = true;
}
}
while (!end);
List<string> received;
Task[] tasks =
{
Task.Factory.StartNew( () =>
{
ThreadSender ts = new ThreadSender();
ts.buffer = toSend;
Console.WriteLine("(T1) waiting before starting...");
Thread.Sleep(7500);
ts.SendInfos();
} ),
Task.Factory.StartNew( async () =>
{
ThreadReceiver tr = new ThreadReceiver();
received = await tr.ReceiveInfos();
} )
};
Task.WaitAll(tasks);
Console.WriteLine("Done.");
Console.ReadKey();
}
}
class ThreadSender
{
// buffer di invio
public List<String> buffer;
// socket per l'invio dei dati
private StreamSocket ss;
public ThreadSender()
{
buffer = new List<string>();
ss = new StreamSocket();
}
public async void SendInfos()
{
HostName hn = new HostName("localhost");
await ss.ConnectAsync(hn, "3000");
StreamWriter sw = new StreamWriter(ss.OutputStream.AsStreamForWrite());
StreamReader sr = new StreamReader(ss.InputStream.AsStreamForRead());
Console.WriteLine($"(T1) Sending line count: {buffer.Count}");
sw.WriteLine(buffer.Count.ToString());
sw.Flush();
foreach (string line in buffer)
{
Console.WriteLine("(T1) sending line: {0}", line);
sw.WriteLine(line);
sw.Flush();
}
Thread.Sleep(5000);
Console.WriteLine("(T1) closing connection");
ss.Dispose();
ss = null;
}
}
class ThreadReceiver
{
// buffer di scrittura
public List<String> buffer = new List<string>();
private StreamSocketListener ssl;
private bool received = false;
private bool error = false;
public ThreadReceiver()
{
ssl = new StreamSocketListener();
}
public async Task<List<string>> ReceiveInfos()
{
ssl.ConnectionReceived += onConnectionReceived;
await ssl.BindServiceNameAsync("3000");
Console.WriteLine("(T2) waiting for connections...");
while (!received)
{
if (error)
{
Console.WriteLine("(T2) closing connection (error occurred)");
return null;
}
Thread.Sleep(2500);
}
Console.WriteLine("(T2) All Received! Closing...");
return buffer;
}
public async void onConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
Console.WriteLine("(T2) received a incoming connection");
Thread.Sleep(2500);
StreamReader sr = new StreamReader(args.Socket.InputStream.AsStreamForRead());
string receivedCountString = await sr.ReadLineAsync();
if (receivedCountString == null)
{
Console.Error.WriteLine("(T2) ERROR: received null value");
error = true;
return;
}
int nToRead = Int32.Parse(receivedCountString);
Console.WriteLine($"(T2) Receiving {nToRead} messages...");
while (nToRead > 0)
{
string receivedString = await sr.ReadLineAsync();
if (receivedString == null)
{
Console.Error.WriteLine("(T2) ERROR: received null value");
error = true;
return;
}
else
Console.WriteLine($"(T2) Received string: {receivedString}");
buffer.Add(receivedString);
nToRead--;
Console.WriteLine($"Remaining {nToRead} messages");
}
received = true;
}
}
}
我