我在C#中有2个项目,一个是服务器,一个是客户端。使用后台工作程序,他们异步聊天。服务器正在发送消息,客户端正在获取它们并正常显示它们,但是如果我从客户端向服务器发送消息,它第一次正常工作,那么它就不再从客户端发送了。之后,尝试从服务器发送到客户端仍然可以正常工作,但客户端将只发送第一条消息。任何人都可以帮我解释原因吗?
编辑: 这个GIF显示了最新发生的事情:https://gyazo.com/ce0803519702d3080ddc57d0ef45ae0c
服务器:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace SeaboltServerHw5
{
public partial class Server : Form
{
String str;
TcpListener listen = new TcpListener(IPAddress.Parse("127.0.0.1"), 18888);
Boolean connected = false;
StreamReader inn;
StreamWriter outt;
Socket sock;
NetworkStream stream;
public Server()
{
InitializeComponent();
serverRun.RunWorkerAsync();
}
private void StartServer()
{
listen.Start();
sock = listen.AcceptSocket();
connected = true;
stream = new NetworkStream(sock);
inn = new StreamReader(stream);
outt = new StreamWriter(stream);
outt.AutoFlush = true;
}
private void serverRun_DoWork(object sender, DoWorkEventArgs e)
{
StartServer();
if (connected == true)
{
str = inn.ReadLine();
}
else
return;
}
private void serverRun_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//lblConnect.Text = "Client Connected.";
rtbData.AppendText("From Client: " + str + "\n");
serverRun.RunWorkerAsync();
}
private void tbEnter_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
String temp = tbEnter.Text;
outt.WriteLine(temp);
rtbData.AppendText("From Server: " + temp + "\n");
tbEnter.Text = "";
}
else
return;
}
}
}
客户端:
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
namespace SeaboltClientHW5
{
public partial class Client : Form
{
String str;
Boolean connected = false;
TcpClient client = new TcpClient();
NetworkStream stream;
StreamReader inn;
StreamWriter outt;
public Client()
{
InitializeComponent();
client.Connect("127.0.0.1", 18888);
bgWork.RunWorkerAsync();
}
public void startClient()
{
connected = true;
stream = client.GetStream();
inn = new StreamReader(stream);
outt = new StreamWriter(stream);
outt.AutoFlush = true;
}
private void bgWork_DoWork(object sender, DoWorkEventArgs e)
{
startClient();
if (connected == true)
{
str = inn.ReadLine();
}
else
return;
}
private void bgWork_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
rtbData.AppendText("From Server: " + str + "\n");
bgWork.RunWorkerAsync();
}
private void tbEnter_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
String temp = tbEnter.Text;
outt.WriteLine(temp);
rtbData.AppendText("From Client: " + temp + "\n");
tbEnter.Text = "";
}
else
return;
}
}
}
答案 0 :(得分:0)
问题是listen.AcceptSocket()
(正在等待新进入连接)不会被调用一次,而是在每条消息之后调用。一旦 Client 启动并且服务器接受第一条消息,它就会第一次成功。但是它第二次等待无限期(直到新客户端启动)并且服务器被卡住了。
这可能就是你有connected
变量的原因 - 但是现在它已经没用了,因为在调用StartServer()
之后,条件if (connected == true)
将始终为真。为确保首次调用listen.AcceptSocket()
,请重写服务器serverRun_DoWork
,如下所示:
private void serverRun_DoWork(object sender, DoWorkEventArgs e)
{
if (!connected)
StartServer();
str = inn.ReadLine();
}
也应该对客户端进行类似的更改,但与服务器不同,它不是问题,因为客户端代码调用client.GetStream()
,如果重复调用,则立即返回现有网络流,因此尽管调用多余client.GetStream()
在每条消息之后,它基本上是无害的。
private void bgWork_DoWork(object sender, DoWorkEventArgs e)
{
if (!connected)
startClient();
str = inn.ReadLine();
}