这是代码,
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
TcpListener listener;
TcpClient remoteClient;
private void Form1_Load(object sender, EventArgs e)
{
listener = new TcpListener(new IPEndPoint(IPAddress.Any, 6000));//ip为服务器IP地址,port为监听的端口
listener.Start();//开启监听
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
remoteClient = listener.AcceptTcpClient();
NetworkStream streamToClient = remoteClient.GetStream();
byte[] buffer = new byte[remoteClient.ReceiveBufferSize]; // BufferSize为缓存的大小
int bytesRead;
try
{
bytesRead = streamToClient.Read(buffer, 0, buffer.Length);
MemoryStream ms = new MemoryStream(buffer);
Image img = Image.FromStream(ms);
this.pictureBox1.Image = img;
}
catch
{
MessageBox.Show("错误!");
return;
}
}
}
而java服务器段则没有这个问题。以下是java代码。
public class ImageServer {
public static ServerSocket ss = null;
public static void main(String args[]) throws IOException{
ss = new ServerSocket(6000);
final ImageFrame frame = new ImageFrame(ss);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
while(true){
frame.panel.getimage();
frame.repaint();
}
}
}
/**
A frame with an image panel
*/
@SuppressWarnings("serial")
class ImageFrame extends JFrame{
public ImagePanel panel;
public ImageFrame(ServerSocket ss){
// get screen dimensions
Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int screenHeight = screenSize.height;
int screenWidth = screenSize.width;
// center frame in screen
setTitle("ImageTest");
setLocation((screenWidth - DEFAULT_WIDTH) / 2, (screenHeight - DEFAULT_HEIGHT) / 2);
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
// add panel to frame
this.getContentPane().setLayout(null);
panel = new ImagePanel(ss);
panel.setSize(640,480);
panel.setLocation(0, 0);
add(panel);
}
public static final int DEFAULT_WIDTH = 640;
public static final int DEFAULT_HEIGHT = 560;
}
/**
A panel that displays a tiled image
*/
@SuppressWarnings("serial")
class ImagePanel extends JPanel {
private ServerSocket ss;
private Image image;
private InputStream ins;
public ImagePanel(ServerSocket ss) {
this.ss = ss;
}
public void getimage() throws IOException{
Socket s = this.ss.accept();
this.ins = s.getInputStream();
this.image = ImageIO.read(ins);
this.ins.close();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
if (image == null) return;
g.drawImage(image, 0, 0, null);
}
}
没看明白,啥延迟?
timer1_Tick 是 timer 的注册事件吗?timer 是立即启动吗?
为什么不用 while(true) 把 AcceptTcpClient 包裹起来,而非要点击一下 button 才去读取?
建议你在这里学习下相关的概念:
1.延迟是 客户端摄像头已经拍到2分钟了,服务器端看到的还是1分钟时的图像
2.timer1_Tick 是 timer 的注册事件,点击按钮 timer启动,每200毫秒执行一次。
3.用while(true) 把 AcceptTcpClient 包裹起来的时候 报错。
谢谢你的建议 ,我去看看。
@宇凡106: 2.timer1_Tick 是 timer 的注册事件,点击按钮 timer启动,每200毫秒执行一次。
你每 200 毫秒才去 AcceptTcpClient,这至少就有 200 毫秒的延迟。socket server 的一般模式就是:
while(accept)
{
// 处理请求,可以在此线程执行,也可以在别的线程执行。
}
原来C#还可以起这样子的作用
可以考虑下是否出现粘包的问题,相信你从摄像头捕获的数据也不是一次性传输完成的吧? 服务端也应该不可能这么设计的吧?
应该是将包分开编号发送的吧?
如果是这样请考虑下粘包的问题