Socket发送图片怎么解决?

论文MVP网 2010-02-01 03:12:38
S给C发送图片,代码如下




S核心代码

// 发送
private void button1_Click(object sender, EventArgs e)
{
MemoryStream ms = new MemoryStream();
MyImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
ms.Position = 0;
myData= new Byte[1024];
myData = ms.ToArray();
MemoryStream ms2 = new MemoryStream();
ms2.Write(myData, 0, myData.Length);
Thread thread = new Thread(new ThreadStart(sendimage));
thread.Start();
}
// 图片发送
private void sendimage()
{
if (!isconnected)
{
IPAddress ip = IPAddress.Parse("192.168.0.2");
IPEndPoint endpoint = new IPEndPoint(ip, 9000);
mysocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
mysocket.Connect(endpoint);

isconnected = true;
}
mysocket.Send(myData);
}


C核心代码
private void Form2_Load(object sender, EventArgs e)
{
Thread thread = new Thread(new ThreadStart(ReceiveImage));
thread.Start();
}

private void ReceiveImage()
{
listenser = new TcpListener(IPAddress.Parse("192.168.0.2"), 9000);
listenser.Start();
socket = listenser.AcceptSocket();
isconnected = true;

}
private void timer1_Tick(object sender, EventArgs e)
{
if (!isconnected)
{
return;
}
//MessageBox.Show("1");
MemoryStream mystream = new MemoryStream();
int number = 0;
// 1024*1024
byte[] imagebyte = new byte[1048576];
mystream.Position = 0;
number = socket.Receive(imagebyte);
if (number > 0)
{
mystream.Write(imagebyte, 0, number);
imagebyte = new byte[1048576];
pictureBox1.Image = Image.FromStream(mystream);
}
else
{
return;
}
}


// 说明,上面代码发送一张图片从S给C可以,没问题,但是发送第2张,用timer就会一直等待接收,屏幕如同卡死
但是如果不用timer,怎么连续接收2张图片呢?他接收一张后,就停止了,并且跳出了新开的进程,怎么让那个进程
ReceiveImage(),一直等待接收图片并显示
...全文
1727 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
weiyiVB 2012-03-17
  • 打赏
  • 举报
回复
我也想知道
LIMINLY520 2011-08-03
  • 打赏
  • 举报
回复
关注中……
小小的学习一下啊
增长见识
samyp1234 2010-08-18
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 x87050418x 的回复:]

C# code

private Socket socket = null;
TcpListener listenser = null;
private bool isconnected = false;
Thread thread = null;
private void Form2_Load(object sender, Ev……
[/Quote]


问题解决了吗?我也想知道啊。
论文MVP网 2010-02-02
  • 打赏
  • 举报
回复
UP
论文MVP网 2010-02-02
  • 打赏
  • 举报
回复

private Socket socket = null;
TcpListener listenser = null;
private bool isconnected = false;
Thread thread = null;
private void Form2_Load(object sender, EventArgs e)
{
thread = new Thread(new ThreadStart(ReceiveImage));
thread.Start();
}
private void ReceiveImage()
{
listenser = new TcpListener(IPAddress.Parse("192.168.0.2"), 9001);
listenser.Start();
socket = listenser.AcceptSocket();
MemoryStream mystream;
byte[] imagebyte = new byte[1048576];
while (true)
{

int number = 0;
mystream = new MemoryStream();
number = socket.Receive(imagebyte);
mystream.Write(imagebyte, 0, number);
if (number <= 0)
{
break;
}
pictureBox1.Image = null;
try
{
// 注意这里,我这里用的是try ,catch接收的图片,因为
// 中途可能有图片接收的丢失byte,所以无法显示,但是本地很少
//出现,但是用在广域网,很多时候出现,导致图片很难被还原,怎么办?
pictureBox1.Image = Image.FromStream(mystream);
}
catch
{
continue;
}
}
mystream.Close();
}




上面这段功能,我在局域网已经测试成功,可以成功接收数据,但是在广域网上很难成功,
好像是图像传递过来后,不能及时被还原,他总走catch,所以我很头疼,怎么解决这个问题呢?
qqiuzaihui 2010-02-01
  • 打赏
  • 举报
回复
欲参考上述代码的完整版本, 请参考 C#入门经典 P828.
ztenv 2010-02-01
  • 打赏
  • 举报
回复
mysocket.Send(myData);
//你直接发送光屁股的数据是有很大问题的,最好给数据穿上衣服,也就是所谓的协议,

//number = socket.Receive(imagebyte);
你怎么能确定就一定能把整张图片接收完呢?
qqiuzaihui 2010-02-01
  • 打赏
  • 举报
回复
1. TcpServer的辅助类
//TcpServer的辅助类
using System;
using System.IO;
using System.Text;

namespace TcpServer
{
/// <summary>
/// 控制台应用程序的帮助类PictureHelper
/// </summary>
public static class PictureHelper
{
//LIST请求:在字节数组中返回文件列表
public static byte[] GetFileListBytes()
{
string[] files = PictureHelper.GetFileList(); //调用GetFileList函数获取文件列表
StringBuilder responseMessage = new StringBuilder();
foreach (string s in files)
{
responseMessage.Append(s);
responseMessage.Append(":");
}
byte[] responseBuffer = Encoding.ASCII.GetBytes(responseMessage.ToString());

return responseBuffer;
}
// 以字符形式返回所有文件的列表, 供GetFileListBytes调用
private static string[] GetFileList()
{
string[] files = Directory.GetFiles(Properties.Settings.Default.PictureDirectory);
for (int i = 0; i < files.Length; i++)
{
files[i] = Path.GetFileName(files[i]);
}
return files;
}
//返回图片文件的字节数组
public static byte[] GetPictureBytes(string filename)
{
FileInfo fileInfo = new FileInfo(filename);
byte[] buffer = new byte[fileInfo.Length];
using (FileStream stream = fileInfo.OpenRead())
{
stream.Read(buffer, 0, buffer.Length);
}
return buffer;
}
}
}


2. 服务器端
//服务器端
#region Using directives
using System;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
#endregion

namespace TcpServer
{
class Program
{
static void Main(string[] args)
{
//创建TcpListener对象, 并指定端口号
System.Net.Sockets.TcpListener listener = new System.Net.Sockets.TcpListener(IPAddress.Any, 8888);
listener.Start(); //启动监听

while (true)
{
const int bufferSize = 256;

TcpClient client = listener.AcceptTcpClient(); //等待客户机与它连接
NetworkStream clientStream = client.GetStream(); //返回一个NetworkStream对象

byte[] buffer = new byte[bufferSize];
int readBytes = 0;
readBytes = clientStream.Read(buffer, 0, bufferSize); //将网络流中的数据读入到字节数组

string request = Encoding.ASCII.GetString(buffer).Substring(0, readBytes); //将字节级数转换为字符串

//根据请求字符串, 把一个图片文件列表或图片字节返回给客户机
if (request.StartsWith("LIST"))
{
byte[] responseBuffer = PictureHelper.GetFileListBytes(); //得到文件列表的字节数组形式
clientStream.Write(responseBuffer, 0, responseBuffer.Length); //写入网络流, 发回客户机
}
else if (request.StartsWith("FILE"))
{
string[] requestMessage = request.Split(':');
string filename = requestMessage[1]; //requestMessage[0]="FILE" requestMessage[1]=文件名
//读出指定的图像文件的数据
byte[] data = File.ReadAllBytes(Path.Combine(Properties.Settings.Default.PictureDirectory, filename));

clientStream.Write(data, 0, data.Length); //写入网络流, 发回客户机
}
else
{
// 未知的请求
}
clientStream.Close(); //关闭连接
}
}
}
}


3. 客户端
#region Using directives
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Text;
#endregion

namespace WinTcpClient
{
partial class PictureClientForm : Form
{
public PictureClientForm()
{
InitializeComponent();
}
//获取文件列表
private void OnListPictures(object sender, EventArgs e)
{
const int bufferSize = 256;

TcpClient client = new TcpClient(); //创建TcipClient对象

IPHostEntry host = Dns.GetHostEntry("192.168.1.109"); //指定服务器地址
client.Connect(host.AddressList[0], 8888); //连接主机

//使用NetworkStream可以把数据发送给服务器,NetworkStream可以使用TcpClient对象的GetStream()方法访问.
//要写入的数据可以使用NetworkStream方法发送给服务器
NetworkStream clientStream = client.GetStream();

string request = "LIST"; //发送LIST请求
byte[] requestBuffer = Encoding.ASCII.GetBytes(request);
clientStream.Write(requestBuffer, 0, requestBuffer.Length);

byte[] responseBuffer = new byte[bufferSize];
MemoryStream memStream = new MemoryStream();
int bytesRead = 0;
do
{
//从服务器返回的数据用clientStream对象的Read()方法读取,由于不能肯定有多少
//数据从服务器上返回,所以使用循环读取数据. 所读取的数据追加到MemoryStream
//中, 该对象可以自动调整大小
bytesRead = clientStream.Read(responseBuffer, 0, bufferSize);
memStream.Write(responseBuffer, 0, bytesRead);
}
while (bytesRead > 0);
clientStream.Close();
client.Close(); //关闭连接

byte[] buffer = memStream.GetBuffer(); //得到字节数组
string response = Encoding.ASCII.GetString(buffer); //转换为字符
string[] fileNames = response.Split(':');
this.listFiles.DataSource = fileNames; //显示文件列表
}
//获得图片
private void OnDownladPicture(object sender, EventArgs e)
{
const int bufferSize = 256;

TcpClient client = new TcpClient(); //创建TcipClient对象
IPHostEntry host = Dns.GetHostEntry("192.168.1.109"); //指定服务器地址
client.Connect(host.AddressList[0], 8888); //连接主机

NetworkStream clientStream = client.GetStream();

string request = "FILE:" + this.listFiles.SelectedItem.ToString(); //设置请求文件
byte[] requestBuffer = Encoding.ASCII.GetBytes(request); //发送FILE请求
clientStream.Write(requestBuffer, 0, requestBuffer.Length);

byte[] responseBuffer = new byte[bufferSize];
MemoryStream memStream = new MemoryStream();
int bytesRead = 0;
do
{
bytesRead = clientStream.Read(responseBuffer, 0, bufferSize);
memStream.Write(responseBuffer, 0, bytesRead); //读出数据
}
while (bytesRead > 0);
clientStream.Close();
client.Close(); //关闭连接

Image picture = Image.FromStream(memStream); //得到图像并显示
this.pictureBox.Image = picture;
}
}
}
wxm3630478 2010-02-01
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 x87050418x 的回复:]
就是玩具,但是麻烦问下我的那个while(true)怎么还是卡?  是把connect放进去还是把就把send放进去啊?  有点晕菜
[/Quote]

用线程了没,没用肯定卡撒-----------在while没循环玩之前一直会卡着.......
论文MVP网 2010-02-01
  • 打赏
  • 举报
回复
有会的没啊? HELP ME
shk123 2010-02-01
  • 打赏
  • 举报
回复
学习了
论文MVP网 2010-02-01
  • 打赏
  • 举报
回复
就是玩具,但是麻烦问下我的那个while(true)怎么还是卡? 是把connect放进去还是把就把send放进去啊? 有点晕菜
  • 打赏
  • 举报
回复
发送端或者接收端,至少一段应该有一个mystream.close()之类的语句。

怎么能定时呢?奇怪,这样的服务器像玩具,不像是服务产品。
  • 打赏
  • 举报
回复
用Socket.Poll或Select多路分离也可以啊,楼主用timer,是不是新手啊,呵呵
ckl881003 2010-02-01
  • 打赏
  • 举报
回复
把接收的代码放在while(true){}里面

110,499

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧