我是.net新新手,目前在用C#写一个服务器程序,客户端别人已写好。在编写过程中,我遇到一些问题卡壳了,郁闷了很久,希望有高手能帮我解答一下!
源程序如下:
public partial class main : Form
{
private TcpListener tl;
private NetworkStream ns;
private Thread th;
public byte[] send_sock;
public int flag;
public delegate object MyDelegate(object temp, Command pack_type, Command pack_parm,int pack_len);
class ClientTcp
{
private NetworkStream ns;
public event MyDelegate MyEvent;
public ClientTcp(NetworkStream ns)
{
this.ns = ns;
}
public void TcpThread()
{
int bytesSize = 0;
byte[] buffer = new byte[2048];
object temp1 = null;
try
{
int iLoc;
while ((iLoc = ns.Read(buffer, 0, buffer.Length)) > 0)
{
Thread.Sleep(3);
if (ns.DataAvailable)
{
int startLoc = iLoc;
byte[] goval = new byte[buffer.Length - iLoc];
iLoc = ns.Read(goval, 0, goval.Length);
goval.CopyTo(buffer, startLoc);
}
cmd7 = (Nodata_cmd)BytesToStuct_nodata(buffer, cmd7);
temp1 = MyEvent(cmd7, pack_type, pack_parm, pack_len); buffer2 = StructToBytes(temp1);
bytesSize = buffer2.Length;
ns.Write(buffer2, 0, bytesSize);
ns.Flush();
try
{
if (ns.CanWrite == true)
{
if (flag != 0)
{
MessageBox.Show("flag:" + flag.ToString());
int bytez = send_pack.Length;
lock (ns)
{
ns.Write(send_pack, 0, bytez);
}
ns.Flush();
flag = 0;
}
}
}
catch (Exception error)
{
MessageBox.Show("出错\n" + error.ToString());
}
}
ns.Flush();
ns.Close();
}
catch (Exception error)
{
MessageBox.Show("clienttcp出错\n" + error.ToString());
}
}
}
public main()
{
CheckForIllegalCrossThreadCalls = false;
InitializeComponent();
Initial_form();
WindowState = FormWindowState.Maximized;
}
private void StartMenuItem1_Click(object sender, EventArgs e)
{
this.socketport.BackColor = System.Drawing.SystemColors.Window;
this.linkstatus.Text = "连接开始...";
port = int.Parse(this.socketport.Text.ToString());
try
{
client_port = port;
tl = new TcpListener(new IPEndPoint(IPAddress.Any, port));
tl.Start();
th = new Thread(new ThreadStart(listen));
th.IsBackground = true;
th.Start();
}
catch (Exception error)
{
MessageBox.Show(error.ToString());
}
}
private void listen()
{
while (true)
{
try
{
sock = tl.AcceptSocket();
ns = new NetworkStream(sock);
ClientTcp ct = new ClientTcp(ns);
ct.MyEvent += new MyDelegate(ct_MyEvent);
Thread th = new Thread(new ThreadStart(ct.TcpThread));
th.IsBackground = true;
th.Start();
}
catch (Exception error)
{
// MessageBox.Show(error.ToString()); //关闭时会报错
}
}
}
object ct_MyEvent(object temp, Command pack_type, Command pack_parm,int pack_len)
{
//对接收到的客户端程序进行处理,并返回一个数据,通过tcpthread中ns.write()发给客户端
}
private void btn1_Click(object sender, EventArgs e)
{
flag=1;
send_pack={.....};
}
问题1、read不能完全读取完数据,具体表现为:客户端发了100个字节的内容,服务器端一次就读了一些数据后,比如30字节的数据,而剩下的过一会儿发过来,在网上搜了一下解决办法,增加以上蓝色标示的代码,貌似没有改善,而那个beginread方法我又不是很会用,请高手帮忙看一下。
问题2、我需要服务器端主动发个包给客户端,即 btn1_Click函数完成的动作。本来想法是在建一个socket,把客户端的ip地址和端口填进来,再通过这个socket发包,(即动作和客户端一样),发现客户端只支持建了一个socket。所以只能在listen()函数中建立起来的socket里动作。我就加了以上红色标示的代码。发现还是没实现。调试时有执行到ns.Write(send_pack, 0, bytez);这句话,可是客户端没有收到相应的内容。不知是不是没有发出去?而且这样写有一个问题是,必须要客户端发东西过来后,我才执行了红色代码。放在别的位置又不执行?哎,我该怎么办了...
问题3、在我这个程序里,sock和ns是一直都连接的吗??
源程序如下:
public partial class main : Form
{
private TcpListener tl;
private NetworkStream ns;
private Thread th;
public byte[] send_sock;
public int flag;
public delegate object MyDelegate(object temp, Command pack_type, Command pack_parm,int pack_len);
class ClientTcp
{
private NetworkStream ns;
public event MyDelegate MyEvent;
public ClientTcp(NetworkStream ns)
{
this.ns = ns;
}
public void TcpThread()
{
int bytesSize = 0;
byte[] buffer = new byte[2048];
object temp1 = null;
try
{
int iLoc;
while ((iLoc = ns.Read(buffer, 0, buffer.Length)) > 0)
{
Thread.Sleep(3);
if (ns.DataAvailable)
{
int startLoc = iLoc;
byte[] goval = new byte[buffer.Length - iLoc];
iLoc = ns.Read(goval, 0, goval.Length);
goval.CopyTo(buffer, startLoc);
}
cmd7 = (Nodata_cmd)BytesToStuct_nodata(buffer, cmd7);
temp1 = MyEvent(cmd7, pack_type, pack_parm, pack_len); buffer2 = StructToBytes(temp1);
bytesSize = buffer2.Length;
ns.Write(buffer2, 0, bytesSize);
ns.Flush();
try
{
if (ns.CanWrite == true)
{
if (flag != 0)
{
MessageBox.Show("flag:" + flag.ToString());
int bytez = send_pack.Length;
lock (ns)
{
ns.Write(send_pack, 0, bytez);
}
ns.Flush();
flag = 0;
}
}
}
catch (Exception error)
{
MessageBox.Show("出错\n" + error.ToString());
}
}
ns.Flush();
ns.Close();
}
catch (Exception error)
{
MessageBox.Show("clienttcp出错\n" + error.ToString());
}
}
}
public main()
{
CheckForIllegalCrossThreadCalls = false;
InitializeComponent();
Initial_form();
WindowState = FormWindowState.Maximized;
}
private void StartMenuItem1_Click(object sender, EventArgs e)
{
this.socketport.BackColor = System.Drawing.SystemColors.Window;
this.linkstatus.Text = "连接开始...";
port = int.Parse(this.socketport.Text.ToString());
try
{
client_port = port;
tl = new TcpListener(new IPEndPoint(IPAddress.Any, port));
tl.Start();
th = new Thread(new ThreadStart(listen));
th.IsBackground = true;
th.Start();
}
catch (Exception error)
{
MessageBox.Show(error.ToString());
}
}
private void listen()
{
while (true)
{
try
{
sock = tl.AcceptSocket();
ns = new NetworkStream(sock);
ClientTcp ct = new ClientTcp(ns);
ct.MyEvent += new MyDelegate(ct_MyEvent);
Thread th = new Thread(new ThreadStart(ct.TcpThread));
th.IsBackground = true;
th.Start();
}
catch (Exception error)
{
// MessageBox.Show(error.ToString()); //关闭时会报错
}
}
}
object ct_MyEvent(object temp, Command pack_type, Command pack_parm,int pack_len)
{
//对接收到的客户端程序进行处理,并返回一个数据,通过tcpthread中ns.write()发给客户端
}
private void btn1_Click(object sender, EventArgs e)
{
flag=1;
send_pack={.....};
}
问题1、read不能完全读取完数据,具体表现为:客户端发了100个字节的内容,服务器端一次就读了一些数据后,比如30字节的数据,而剩下的过一会儿发过来,在网上搜了一下解决办法,增加以上蓝色标示的代码,貌似没有改善,而那个beginread方法我又不是很会用,请高手帮忙看一下。
问题2、我需要服务器端主动发个包给客户端,即 btn1_Click函数完成的动作。本来想法是在建一个socket,把客户端的ip地址和端口填进来,再通过这个socket发包,(即动作和客户端一样),发现客户端只支持建了一个socket。所以只能在listen()函数中建立起来的socket里动作。我就加了以上红色标示的代码。发现还是没实现。调试时有执行到ns.Write(send_pack, 0, bytez);这句话,可是客户端没有收到相应的内容。不知是不是没有发出去?而且这样写有一个问题是,必须要客户端发东西过来后,我才执行了红色代码。放在别的位置又不执行?哎,我该怎么办了...
问题3、在我这个程序里,sock和ns是一直都连接的吗??
解决方案 »
- GridView添加空行的问题
- 想让用户在form上拖拽直线连接两个控件怎么实现?
- 学习C# 介绍本书@@2
- [攒分贴]用QueryTable向excel批量导入数据
- 如果找到一个NET框架函数,如何一次很快找到它属于哪个类和哪个命名空间,而不是在海洋般的msdn中大量消耗宝贵的时间和精力。
- 询问:(Winform)关于在vs2005下使用WebBrowser控件加载flash的问题
- 不能把数据从数据库读到dataset里
- 如何在C#中实现批量删除啊?
- 让自定义控件半透明
- 急,想下载一个网上调查的源码(C#),有没有推荐的网站.
- “不能引用已有的对象,除非复制已有的引用”是什么意思?(高手help)
- C# 如何给DataGridView中添加一个时间控件
1.Read和Write本来就不能一一对应,读数据的时候只能循环读取直到无数据可读。
2.作为服务端,应该是需要客户端主动连接的,但不需要客户端先发送数据。至于为什么客户端没有收到,应该是客户端没有进入数据收发的动作。
3.这个就问你自己了。客户端连接以后,只要没有断开动作,或者网络上出现其他情况,应该可以视为是保持着连接的。
Thread.Sleep(3);
if (ns.DataAvailable)
{
int startLoc = iLoc;
byte[] goval = new byte[buffer.Length - iLoc];
iLoc = ns.Read(goval, 0, goval.Length);
goval.CopyTo(buffer, startLoc);
}
蓝色部分
我是.net新新手,目前在用C#写一个服务器程序,客户端别人已写好。在编写过程中,我遇到一些问题卡壳了,郁闷了很久,希望有高手能帮我解答一下!
源程序如下:
public partial class main : Form
{
private TcpListener tl;
private NetworkStream ns;
private Thread th;
public byte[] send_sock;
public int flag;
public delegate object MyDelegate(object temp, Command pack_type, Command pack_parm,int pack_len);
class ClientTcp
{
private NetworkStream ns;
public event MyDelegate MyEvent;
public ClientTcp(NetworkStream ns)
{
this.ns = ns;
}
public void TcpThread()
{
int bytesSize = 0;
byte[] buffer = new byte[2048];
object temp1 = null;
try
{
int iLoc;
while ((iLoc = ns.Read(buffer, 0, buffer.Length)) > 0)
{
Thread.Sleep(3);
if (ns.DataAvailable)
{
int startLoc = iLoc;
byte[] goval = new byte[buffer.Length - iLoc];
iLoc = ns.Read(goval, 0, goval.Length);
goval.CopyTo(buffer, startLoc);
}
cmd7 = (Nodata_cmd)BytesToStuct_nodata(buffer, cmd7);
temp1 = MyEvent(cmd7, pack_type, pack_parm, pack_len); buffer2 = StructToBytes(temp1);
bytesSize = buffer2.Length;
ns.Write(buffer2, 0, bytesSize);
ns.Flush();
try
{
if (ns.CanWrite == true)
{
if (flag != 0)
{
MessageBox.Show("flag:" + flag.ToString());
int bytez = send_pack.Length;
lock (ns)
{
ns.Write(send_pack, 0, bytez);
}
ns.Flush();
flag = 0;
}
}
}
catch (Exception error)
{
MessageBox.Show("出错\n" + error.ToString());
}
对于你的答复,我理解是这样的。
1.Read和Write本来就不能一一对应,读数据的时候只能循环读取直到无数据可读。我有把蓝色代码从读取中抽出来,放到while(ns.read)循环外,不过好像没有改善,不知道为什么、
2.作为服务端,应该是需要客户端主动连接的,但不需要客户端先发送数据。至于为什么客户端没有收到,应该是客户端没有进入数据收发的动作。。我自己认为是服务器打开,并已经能够收到客户端的数据了,那个sock应该还是活着的。ns是全局变量,也应该是可用的,所以把蓝色代码放在btn1_Click里面应该就能即时响应的,可是实际上运行后会死在那边,不知为何3.这个就问你自己了。客户端连接以后,只要没有断开动作,或者网络上出现其他情况,应该可以视为是保持着连接的。。我认为是连着的...可是不知道为什么客户端收到tcpthread的第一个ns.write,却收不到第二个ns.write
2.即使连接仍然保持,如果客户端不执行Read,仍然不会收到数据。
3.同2。
我能确认连接时保持的,而且客户端能够read。因为我用别的软件模拟过我要的效果,苦于没有代码,不知道别人怎么实现的。而且很奇怪的是,buffer2 = StructToBytes(temp1);
bytesSize = buffer2.Length;
[color=#FF0000]ns.Write(buffer2, 0, bytesSize);执行了client已收到
ns.Flush();
try
{
if (ns.CanWrite == true)
{
if (flag != 0)
{
MessageBox.Show("flag:" + flag.ToString());
int bytez = send_pack.Length;
lock (ns)
{
ns.Write(send_pack, 0, bytez);客户端没反应 }
ns.Flush();
flag = 0;
}
[/color]
2.试着去掉lock。