如题.发送端和接收端同是C/S程序时,程序运行正常.但是当发送端仍是c/s版本,而把接收端改成b/s版本web程序的时候(代码除了把picturebox改成image控件,其他完全相似),接收端点击"接收"按钮时,提示错误:-------------------------------------------连接错误System.InvalidOperationException: 在执行此操作前必须先调用 Bind 方法。 在 System.Net.Sockets.Socket.Accept() 在 _Default.Button2_Click(Object sender, EventArgs e) 位置 c:\Inetpub\wwwroot\PicShow\Default.aspx.cs:行号 46 实际上我刚开始在"监听"按钮中已经监听了,已经bind了.C/S版本中就顺利通过了,为什么转换成B/S版本中就这样提示呢.如果再次bind,系统会提示"套接字端口只能使用一次什么的".现帖出接收端代码如下:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;using System.Drawing;
using System.Text;
using System.Net;
using System.IO;
using System.Net.Sockets;
using System.Drawing.Imaging;public partial class _Default : System.Web.UI.Page
{
System.Net.Sockets.Socket receivesocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
//设置接收数据的地址
System.Net.IPEndPoint hostipendpoint = new System.Net.IPEndPoint(System.Net.IPAddress.Any,8080); protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
}
}
/// <summary>
/// 监听
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Button1_Click(object sender, EventArgs e)
{
receivesocket.Bind(hostipendpoint);
//监听
receivesocket.Listen(2);
this.Label1.Text = "已经开始监听";
}
//连接
protected void Button2_Click(object sender, EventArgs e)
{
try
{
//设置接收数据缓冲区的大小
byte[] b = new byte[1024 * 4]; //1024* 4
System.Net.Sockets.Socket hostsocket = receivesocket.Accept();
//如何确定该数组大小
System.IO.MemoryStream fs = new System.IO.MemoryStream(); int got = 0;
int datalength = 0; while (true)
{
got = hostsocket.Receive(b);
fs.Write(b, 0, got);
if (got > 0)
datalength = datalength + got;
else
break;
}
Bitmap Img = new Bitmap(fs);
Img.Save("e:\\新建文件夹\\MyJpeg.jpg", ImageFormat.Jpeg);
this.Image1.ImageUrl = @"e:\MyJpeg.jpg";
//关闭写文件流
fs.Close();
//关闭接收数据的Socket
hostsocket.Shutdown(System.Net.Sockets.SocketShutdown.Receive);
hostsocket.Close();
this.Response.Write("传输成功!"); }
catch (Exception se)
{
this.Response.Write("连接错误" +se.ToString());
return;
}
}
}
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;using System.Drawing;
using System.Text;
using System.Net;
using System.IO;
using System.Net.Sockets;
using System.Drawing.Imaging;public partial class _Default : System.Web.UI.Page
{
System.Net.Sockets.Socket receivesocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
//设置接收数据的地址
System.Net.IPEndPoint hostipendpoint = new System.Net.IPEndPoint(System.Net.IPAddress.Any,8080); protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
}
}
/// <summary>
/// 监听
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Button1_Click(object sender, EventArgs e)
{
receivesocket.Bind(hostipendpoint);
//监听
receivesocket.Listen(2);
this.Label1.Text = "已经开始监听";
}
//连接
protected void Button2_Click(object sender, EventArgs e)
{
try
{
//设置接收数据缓冲区的大小
byte[] b = new byte[1024 * 4]; //1024* 4
System.Net.Sockets.Socket hostsocket = receivesocket.Accept();
//如何确定该数组大小
System.IO.MemoryStream fs = new System.IO.MemoryStream(); int got = 0;
int datalength = 0; while (true)
{
got = hostsocket.Receive(b);
fs.Write(b, 0, got);
if (got > 0)
datalength = datalength + got;
else
break;
}
Bitmap Img = new Bitmap(fs);
Img.Save("e:\\新建文件夹\\MyJpeg.jpg", ImageFormat.Jpeg);
this.Image1.ImageUrl = @"e:\MyJpeg.jpg";
//关闭写文件流
fs.Close();
//关闭接收数据的Socket
hostsocket.Shutdown(System.Net.Sockets.SocketShutdown.Receive);
hostsocket.Close();
this.Response.Write("传输成功!"); }
catch (Exception se)
{
this.Response.Write("连接错误" +se.ToString());
return;
}
}
}
你的button1按钮点击里Bind Socket,这个时候确实bind上了,点button2的时候,页面需要重新加载,
因此你在页面级别定义变量的代码:
System.Net.Sockets.Socket receivesocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
又被执行了一次,那么这个新的recervesocket是不是会bind呢?答案是不会!因此就会提示你 连接错误System.InvalidOperationException: 在执行此操作前必须先调用 Bind 方法为什么你在button2里再次bind会报错呢?
因为你前面一次的对象bind了端口8080,没有释放,因此你再次bind就会提示 “套接字端口只能使用一次什么的”看完我的介绍你再去调试下代码,把断点下在
System.Net.Sockets.Socket receivesocket = new XXXX 这里
System.Net.Sockets.Socket receivesocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
改为:System.Net.Sockets.Socket receivesocket = null;在page_load里:
if (!this.IsPostBack)
{
receivesocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
}然后你在调试下程序,这个方法可以是你的程序可用,但个人认为不是好的解决方案好的解决方案应该是在WEB服务器上写一个服务去取数据,WEB只负责数据的展示
WEB端用异步的方式解决取数据和显示上的时间差,比如出现一个loading...,
System.Net.Sockets.Socket receivesocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
改为:System.Net.Sockets.Socket receivesocket = null; 在page_load里:
if (!this.IsPostBack)
{
receivesocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这样改过以后,在点击"监听"按钮的时候,出现下列提示:
未将对象引用设置到对象的实例。
说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。 异常详细信息: System.NullReferenceException: 未将对象引用设置到对象的实例。源错误:
行 84: protected void Button1_Click(object sender, EventArgs e)
行 85: {
行 86: receivesocket.Bind(hostipendpoint);
行 87: //监听
行 88: receivesocket.Listen(2);
因为页面加载的时候receivesocket被置NULL了改改:public System.Net.Sockets.Socket receivesocket
{
get{
return (System.Net.Sockets.Socket)Session["receivesocket"];
}
set
{
Session["receivesocket"] = value;
}
}page_load里:
if (!this.IsPostBack)
{
receivesocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
改过的代码如下:
public partial class _Default : System.Web.UI.Page
{
public System.Net.Sockets.Socket receivesocket
{
get
{
return (System.Net.Sockets.Socket)Session["receivesocket"];
}
set
{
Session["receivesocket"] = value;
}
}
//设置接收数据的地址
System.Net.IPEndPoint hostipendpoint = new System.Net.IPEndPoint(System.Net.IPAddress.Any,8888); protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
receivesocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
}
} /// <summary>
/// 监听
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Button1_Click(object sender, EventArgs e)
{
receivesocket.Bind(hostipendpoint);
//监听
receivesocket.Listen(2);
this.Label1.Text = "已经开始监听";
}
//连接
protected void Button2_Click(object sender, EventArgs e)
{
try
{
//设置接收数据缓冲区的大小
byte[] b = new byte[1024 * 4]; //1024* 4
System.Net.Sockets.Socket hostsocket = receivesocket.Accept(); -----------------------------------------改后依然提示要"bind"
//如何确定该数组大小
System.IO.MemoryStream fs = new System.IO.MemoryStream(); int got = 0;
int datalength = 0; while (true)
{
got = hostsocket.Receive(b);
fs.Write(b, 0, got);
if (got > 0)
datalength = datalength + got;
else
break;
}
Bitmap Img = new Bitmap(fs);
Img.Save("e:\\新建文件夹\\MyJpeg.jpg", ImageFormat.Jpeg);
this.Image1.ImageUrl = @"e:\MyJpeg.jpg";
//关闭写文件流
fs.Close();
//关闭接收数据的Socket
hostsocket.Shutdown(System.Net.Sockets.SocketShutdown.Receive);
hostsocket.Close();
this.Response.Write("传输成功!"); }
catch (Exception se)
{
this.Response.Write("连接错误" +se.ToString());
return;
}
}
}
protected void Button2_Click(object sender, EventArgs e)
{
try
{
//设置接收数据缓冲区的大小
byte[] b = new byte[1024 * 4]; //1024* 4
System.Net.Sockets.Socket hostsocket = receivesocket.Accept(); -----------------------------------------改后依然提示要"bind"
//如何确定该数组大小 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
这地方写的少了什么或者多了什么呀
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;using System.Net.Sockets;
using System.Net;public partial class Default4 : System.Web.UI.Page
{ private Socket recs
{
get
{
return (Socket)Session["resc"];
}
set
{
Session["resc"] = value;
}
} private IPEndPoint hostip = new IPEndPoint(IPAddress.Any, 8083); protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
recs = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
}
}
protected void button1_Click(object sender, EventArgs e)
{
recs.Bind(hostip);
recs.Listen(2);
}
protected void Button2_Click(object sender, EventArgs e)
{
try
{
Socket newscr = recs.Accept();
Response.Write("accepted");
}
catch (System.Exception ex)
{
Response.Write(ex.Message);
}
}
}
我的代码测试通过,一切正常
VS2005 + WINXP
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Imaging;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Example023_屏幕捕获程序
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
private static extern bool BitBlt(
IntPtr hdcDest, //目标设备的句柄
int nXDest, // 目标对象的左上角的X坐标
int nYDest, // 目标对象的左上角的X坐标
int nWidth, // 目标对象的矩形的宽度
int nHeight, // 目标对象的矩形的长度
IntPtr hdcSrc, // 源设备的句柄
int nXSrc, // 源对象的左上角的X坐标
int nYSrc, // 源对象的左上角的X坐标
System.Int32 dwRop // 光栅的操作值
); [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]
private static extern IntPtr CreateDC(
string lpszDriver, // 驱动名称
string lpszDevice, // 设备名称
string lpszOutput, // 无用,可以设定位"NULL"
IntPtr lpInitData // 任意的打印机数据
); System.Net.Sockets.Socket sendsocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
//实例化socket
System.Net.IPEndPoint ipendpiont = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("192.168.1.100"),8083); //服务器的IP和端口//因为客户端只是用来向特定的服务器发送信息,所以不需要绑定本机的IP和端口。不需要监听。
private void button2_Click(object sender, EventArgs e)
{ // sendsocket.Connect(ipendpiont);
try
{
sendsocket.Connect(ipendpiont);
MessageBox.Show("连接成功!");
}
catch (Exception se)
{
MessageBox.Show("连接错误" + se.Message, "提示信息", MessageBoxButtons.RetryCancel, MessageBoxIcon.Information);
return;
}
} private void button1_Click(object sender, EventArgs e)
{
try
{
this.Hide();
IntPtr dc1 = CreateDC("DISPLAY", null, null, (IntPtr)null);
//创建显示器的DC
Graphics g1 = Graphics.FromHdc(dc1);
//由一个指定设备的句柄创建一个新的Graphics对象
Bitmap MyImage = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, g1);
//根据屏幕大小创建一个与之相同大小的Bitmap对象
Graphics g2 = Graphics.FromImage(MyImage);
//获得屏幕的句柄
IntPtr dc3 = g1.GetHdc();
//获得位图的句柄
IntPtr dc2 = g2.GetHdc();
//把当前屏幕捕获到位图对象中
BitBlt(dc2, 0, 0, Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height, dc3, 0, 0, 13369376);
//把当前屏幕拷贝到位图中
g1.ReleaseHdc(dc3);
//释放屏幕句柄
g2.ReleaseHdc(dc2);
//释放位图句柄
MyImage.Save("d:\\新建文件夹\\MyJpeg.jpg", ImageFormat.Jpeg); //当然你也可以根据自己的需要,把屏幕以其他图片的格式来保存,如果你想把图片保存为位图文件,可以把"ImageFormat.Jpeg"改换成"ImageFormat.Bmp";想把图片保存为Gif文件,就把"ImageFormat.Jpeg"改换成"ImageFormat.Gif"。你可以保存的文件类型大概有十多种,这里就不一一介绍了,当然你也要相应改变保存文件的后缀。
pictureBox1.Image = MyImage;
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage; //本程序所用控件为1个按狃,一个panel,一个picturebox,其中panel的属性Autoscroll =true; picturebox的属性SizeMode =AutoSize; 然后只要改变pictureBox的大小,图象就会跟着改变大小,如果把这句去掉的话,就可以实现图象按panel滚动条移动而查看全图。 // MessageBox.Show("已经把当前屏幕保存到D:\\MyJpeg.jpg文件中!");
this.Show();
//***************************************************************************************开始使用socket发送文件*********************************************************//
//建立终结点
System.IO.MemoryStream Stream = new System.IO.MemoryStream();
pictureBox1.Image.Save(Stream, System.Drawing.Imaging.ImageFormat.Bmp);//存储为bmp图象
// pictureBox1.Image.Save(Stream, System.Drawing.Imaging.ImageFormat.Jpeg); //不想存储为bmp图象,想存储为jpeg图象
byte[] b = Stream.ToArray();
//连接远程计算机
sendsocket.Send(b);
//发送 Stream.Close();
sendsocket.Shutdown(System.Net.Sockets.SocketShutdown.Send);
//关闭发送连接
sendsocket.Close(); //关闭本 //***********************************************************************************************************end*******************************************************// }
catch (Exception ex)
{
string s = ex.ToString();
return;
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (sendsocket.Connected)
{
this.label1.Text= "连接成功"; }
}
}
}
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;using System.Drawing;
using System.Text;
using System.Net;
using System.IO;
using System.Net.Sockets;
using System.Drawing.Imaging;public partial class _Default : System.Web.UI.Page
{
private System.Net.Sockets.Socket receivesocket
{
get
{
return (System.Net.Sockets.Socket)Session["receivesocket"];
}
set
{
Session["receivesocket"] = value;
}
}
//设置接收数据的地址
private System.Net.IPEndPoint hostipendpoint = new System.Net.IPEndPoint(System.Net.IPAddress.Any,8083); protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
receivesocket = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
}
} /// <summary>
/// 监听
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Button1_Click(object sender, EventArgs e)
{
receivesocket.Bind(hostipendpoint);
//监听
receivesocket.Listen(2);
this.Label1.Text = "已经开始监听";
}
//连接
protected void Button2_Click(object sender, EventArgs e)
{
try
{
//设置接收数据缓冲区的大小
byte[] b = new byte[1024 * 4]; //1024* 4
System.Net.Sockets.Socket hostsocket = receivesocket.Accept();
//如何确定该数组大小
System.IO.MemoryStream fs = new System.IO.MemoryStream(); int got = 0;
int datalength = 0; while (true)
{
got = hostsocket.Receive(b);
fs.Write(b, 0, got);
if (got > 0)
datalength = datalength + got;
else
break;
}
Bitmap Img = new Bitmap(fs);
Img.Save("e:\\新建文件夹\\MyJpeg.jpg", ImageFormat.Jpeg);
this.Image1.ImageUrl = @"e:\MyJpeg.jpg";
//关闭写文件流
fs.Close();
//关闭接收数据的Socket
hostsocket.Shutdown(System.Net.Sockets.SocketShutdown.Receive);
hostsocket.Close();
this.Response.Write("传输成功!"); }
catch (Exception se)
{
this.Response.Write("连接错误" +se.ToString());
return;
}
}
}
先把你的核心调通吧,网络通信都没建设起来,搞啥都没用别管那么多外部代码,核心就是socket建立连接的过程嘛你帖那么长代码,看起来就头晕呢
所以你的服务端能连接到C,并指挥C抓屏幕,传数据等但是问题就在这里,你如何获取我的IP地址并连接上来?局域网内这个没有一点问题,客户端C上报到服务器就好了
但是,互联网上就不是那么简单了,有可能客户端C是在一个子网内部的,通过路由上网,
这样的情况你是连接不上客户端C的当然,这个问题也是可以解决的,参考下P2P的原理