在多线程环境下使用udpclient进行异步UDP接收出现“访问已注销对象”的异常,怎么办? 5C

最近打算使用C#写一个仿飞秋的局域网即时通信工具,但是在使用多线程异步收发UDP数据时老是出现“访问对象已注销”的异常,查了好久都没有找到原因,只能求助于网友啦。
完整代码可以在我的github上下载:WAW
说说具体情况吧:
1.为了进行udp数据的异步接收,我写了一个异步接收类AsyncUDPclient。

  public class AsyncUDPclient
    {
        private IPEndPoint recEP, sendEP;
        private UdpClient udpReceive, udpSend;
        private UdpState udpReceiveState, udpSendState;

        //定义消息接收事件
        public event MessageReceivedEventHandle MessageReceived;

        // 异步状态同步
        //private ManualResetEvent sendDone = new ManualResetEvent(false);
        //private ManualResetEvent receiveDone = new ManualResetEvent(false);

        public AsyncUDPclient()
        {
            recEP = new IPEndPoint(IPAddress.Any, InfoSet.IpPort.Port);//允许从任意远程主机终节点接收数据
            sendEP = new IPEndPoint(IPAddress.Any, InfoSet.IpPort.Port);//允许向任意远程主机终节点发送数据,发送和接收使用同一个端口
            udpReceive = new UdpClient(recEP);
            udpSend = new UdpClient();

            udpReceiveState = new UdpState();
            udpReceiveState.udpClient = udpReceive;
            udpReceiveState.ipEndPoint = recEP;

            udpSendState = new UdpState();
            udpSendState.udpClient = udpSend;
            udpSendState.ipEndPoint = sendEP;
        }

        public void ReceiveMsg()
        {
            udpReceive.BeginReceive(new AsyncCallback(ReceiveCallback), udpReceiveState);
            //receiveDone.WaitOne();
        }

        private void ReceiveCallback(IAsyncResult iar)
        {
            UdpState s = iar.AsyncState as UdpState;
            if(iar.IsCompleted)
            {
                IPEndPoint ep = s.ipEndPoint;
                UdpClient u = s.udpClient;
                Byte[] receiveBytes = u.EndReceive(iar, ref ep);

                //调用消息接收事件处理方法
                MessageEventArgs args = new MessageEventArgs();
                args.remoteIP = ep;
                args.buffer = receiveBytes;
                if (MessageReceived != null)
                {
                    MessageReceived(this, args);
                }
                //receiveDone.Set();

                u.BeginReceive(new AsyncCallback(ReceiveCallback), s);//此处需要验证s.ipEndPoint的值是否已经变化?
            }
        }

        public void SendMsg(byte[] datagram,int bytes,IPEndPoint sendEP)
        {
            udpSendState.ipEndPoint = sendEP;
            udpSend.BeginSend(datagram, bytes,sendEP, new AsyncCallback(SendCallback), udpSendState);
            Thread.Sleep(100);
        }

        private void SendCallback(IAsyncResult iar)
        {
            UdpState s = iar.AsyncState as UdpState;
            s.udpClient.EndSend(iar);
            //sendDone.Set();
        }

        public void StopClient()
        {
            udpSend.Close();
            udpReceive.Close();
            Thread.Sleep(100);
        }
    }

    /// <summary>
    /// 消息接收事件委托
    /// </summary>
    /// <param name="Sender"></param>
    /// <param name="e"></param>
    public delegate void MessageReceivedEventHandle(object Sender, MessageEventArgs e);
    public class MessageEventArgs : EventArgs
    {
        public byte[] buffer;
        public IPEndPoint remoteIP;

        public MessageEventArgs() : base()
        {
            remoteIP = new IPEndPoint(IPAddress.Any, 0);
        }
    }
    public class UdpState
    {
        public UdpClient udpClient;
        public IPEndPoint ipEndPoint;
    }

2.当程序启动之后,在程序主窗口类frmMain.cs里开了一个新线程监听指定端口,用于接收UDP数据,然后主窗口程序广播上线消息。

     public partial class frmMain : Form
    {
        //用于整个程序收发数据的对象
        public AsyncUDPclient AsyncUDP;

        private Thread udplistenthread;
        private DataReceive startreceive;

        public frmMain()
        {
            InitializeComponent();
            _userstate = wawState.SignIn;
            Rectangle rec = Screen.GetWorkingArea(this);
            this.ClientSize = new Size(234, rec.Height - 100);
            this.Location = new Point((int)(rec.Width * 0.8), (int)(rec.Height * 0.05));
            this.MaximumSize = new Size(260, rec.Height);
            this.MinimumSize = new Size(234, 100);
            this.chTag.Width = 0;
            this.chUser.Width = (int)(this.lvwUsers.Width * 0.3);
            this.chIP.Width = (int)(this.lvwUsers.Width * 0.4);
            this.chHostname.Width = this.lvwUsers.Width - this.chUser.Width - this.chHostname.Width;

            AsyncUDP = new AsyncUDPclient();//收发数据对象初始化
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            //开启监听线程,新线程执行StartListenUdp方法
            startreceive = new DataReceive(lvwUsers, lblUserCount,AsyncUDP);
            udplistenthread = new Thread(new ThreadStart(startreceive.StartListenUdp));
            udplistenthread.IsBackground = true;
            udplistenthread.Start();

            MsgBoardCast boardcast = new MsgBoardCast(AsyncUDP);
            //boardcast.BoardCast(wawCMD.WAW_BC_SIGNIN);

            int i = 0;
            foreach(IPAddress addr in Dns.GetHostEntry(Dns.GetHostName()).AddressList)
            {
                if(addr.AddressFamily==AddressFamily.InterNetwork)
                {
                    cmbIpList.Items.Add(addr.ToString());
                    if (addr.ToString()==InfoSet.IpPort.Address.ToString())
                    {
                        cmbIpList.SelectedIndex = i;
                    }
                    i++;                    
                }
            }
        }
        }

StartListenUdp方法如下(就是调用异步接收类AsyncUDPclient的ReceiveMsg方法开始异步接收):

        public void StartListenUdp()
        {          
            AsyncClient.MessageReceived += new MessageReceivedEventHandle(DataConfig);
            AsyncClient.ReceiveMsg();
        }

但是在运行过程中一直很出现异常,貌似是说调用udpclient对象是该对象已经注销,但我检查了很久都没有查处问题,这个问题一直卡了我整整两周时间,实在是没办法了。
以下是调试报错截图:
图片说明

3个回答

可以考虑在 udpReceive.Close(); 后设置一个变量,然后在ReceiveCallback check一下这个变量确定要访问的对象是否已经被释放

shangjindetudou
3-_-3 我调试过了,只要是跳到ReceiveCallback回调函数中,变量就是null,我最近在考虑是不是此类调用不能在多线程下使用啊?
一年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
C# udpClient 发udp变成了dcp
如题,用wireshark截的包变成了DCP Protection,我是要发两个udp报文,只有一个udp会出现这种情况,另外的一个udp正常发送。请问DCP Protection是什么,什么情况会导致这种情况发生,我只是简单的使用udpclient的send方法,区别在于两个字节流数据不同
关于udpclient接收时候假死的问题
我用udpclient接收消息的时候,总是在Receive时候就卡着不动了,也用了线程,不知道是什么原因,哪位大神给我看看 //发送代码 UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Any, 0)); IPEndPoint endpoint = new IPEndPoint(IPAddress.Parse("255.255.255.255"), 1025); byte[] buf = Encoding.Default.GetBytes("Are You Device?"); try { client.Send(buf, buf.Length, endpoint); client.Close(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } //接收按钮 private void button2_Click(object sender, EventArgs e) { Thread t = new Thread(new ThreadStart(RecvThread)); t.Start(); t.IsBackground = true; } //接收代码 public void RecvThread() { while (true) { UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Any, 1025)); IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, 0); try { byte[] buf = client.Receive(ref endpoint); string msg = Encoding.ASCII.GetString(buf); //string strReceive = string.Format((endpoint as IPEndPoint).Address.ToString() + ":" + (endpoint as IPEndPoint).Port.ToString()); Console.WriteLine(msg.ToString()); client.Close(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } }
C # UDPClient 通讯连续发送消息
如何实现UDP通讯时的连续发送消息,目前我只实现发送一条消息就不能再发送,在网上搜找后说要使用多线程,但是我不会啊,请求高手指导》 Server: private void btRec_Click(object sender, EventArgs e) { //在本機指定的端口接收 IPEndPoint remoteIpEndIPoint = new IPEndPoint(IPAddress.Any, 8002); udpReceive = new UdpClient(remoteIpEndIPoint); IPEndPoint iep = new IPEndPoint(IPAddress.Any, 0); //接收從遠程主機發送過來的消息 //while (true) //{ //ref表示引用類型 IPPoint實例接收消息 byte[] receiveBytes = udpReceive.Receive(ref iep); string returnData = Encoding.UTF8.GetString(receiveBytes); txtSerRev.Text = returnData; string strBack = "I am fine. Your IP address is " +iep.ToString(); byte[] data = Encoding.ASCII.GetBytes(strBack); udpReceive.Send(data,data.Length,iep); //} } CLient : private void btSendMsg_Click(object sender, EventArgs e) { //初始化UdpClient udpSend = new UdpClient(); //實際使用時應將192.168.80.128該為服務器的遠程IP IPAddress remoteIPAddress = IPAddress.Parse(txtServerIP.Text); IPEndPoint remoteIPEndPoint = new IPEndPoint(remoteIPAddress, 8002); //將發送內容轉換為字節數組 byte[] bytes = System.Text.Encoding.UTF8.GetBytes(txtSend.Text); udpSend.Send(bytes, bytes.Length, remoteIPEndPoint); bytes = udpSend.Receive(ref remoteIPEndPoint); string str = Encoding.UTF8.GetString(bytes, 0, bytes.Length); txtRec.Text = str; }
udp socket通讯问题!
在使用udp通讯的时候,在网上找寻的资料几乎全是使用两个udpclient来用于一个专门接收的socket,另一个用来发送。为什么不直接使用一个进行发送和接收,这又不会相互影响,而且还省一些消耗。有大神能帮我解答疑惑么!?
c# UDP组网 客户端发送接收
需要组网 网段 255.255.0.22 端口号 2031 我这是客户端 需要发送和接收数据 现在自己写的代码 服务器接收不到数据 用网络调试助手调试 服务器可以接收 表示网络连通的 各位大神 帮忙看看 很着急 第一次做UDP组网 组网部分全部代码如下: UdpClient ZuBoClient; IPEndPoint ZuBoIp; int zuboPort = 2031; ZuBoClient = new UdpClient(zuboPort); ZuBoIp = new IPEndPoint(IPAddress.Parse("225.255.0.22"), 2031); ZuBoClient.JoinMulticastGroup(IPAddress.Parse("225.255.0.22")); ZuBoClient.Send(aliveBuf, aliveBuf.Length, ZuBoIp); alivebuf是所发数据
delphi中的udpclient如何接收来自udpserver发送的消息?
udpclient需要先给udpserver发送消息,二者才能建立连接。 我自己简单写了一下client只能发送不能接收,问题在哪里呢? 还有就是udpclient在和调试器连接的时候是正常的能收能发,请各位大神请教! procedure TForm1.FormCreate(Sender: TObject); begin IdUDPClient1.Active := true; end; procedure TForm1.Button1Click(Sender: TObject); begin IdUDPClient1.Send('127.0.0.1', 8001, Edit1.Text); end; procedure TForm1.Button2Click(Sender: TObject); var s: string; begin try s := Form1.IdUDPClient1.ReceiveString(); if length(s) > 1 then Form1.Memo1.Lines.Append(s); finally end; end;
C# UDP通讯,外网客户端向内网服务器发送数据接受不到
内网发送接收消息没问题,外网路由器做了UDP映射,客户端发送数据,能在内网PC电脑上抓包出来,但是服务器接收不到这个消息 private void freeDNS_Server_Load(object sender, EventArgs e) { receiveClient = new UdpClient(port); Thread myThread = new Thread(ReceiveData); myThread.IsBackground = true; myThread.Start(); } //在后台运行的接收线程 private void ReceiveData() { //在本机指定的端口接收 UdpState udpState = new UdpState(); udpState.ipEndPoint = null; udpState.udpClient = receiveClient; //接收从远程主机发送过来的信息; IAsyncResult ar = udpState.udpClient.BeginReceive(ReceiveUdpClientCallback, udpState); ar.AsyncWaitHandle.WaitOne(); MessageBox.Show("线程结束"); } //接收信息回调方法 void ReceiveUdpClientCallback(IAsyncResult ar) { try { UdpClient u = (UdpClient)((UdpState)(ar.AsyncState)).udpClient; IPEndPoint remote = (IPEndPoint)((UdpState)(ar.AsyncState)).ipEndPoint; Byte[] receiveBytes = u.EndReceive(ar, ref remote); string str = Encoding.UTF8.GetString(receiveBytes, 0, receiveBytes.Length); AddItem(listBox_freeDNS_Server, string.Format("来自{0}:{1}", remote, str)); ReceiveData();//继续接受数据 } catch (Exception ex) { AddItem(listBox_freeDNS_Server, string.Format("错误信息{0}", ex.ToString())); } } delegate void AddListBoxItemCallback(string text); private void AddListBoxItem(string text) { //如果listBoxReceive被不同的线程访问则通过委托处理; if (listBox_freeDNS_Server.InvokeRequired) { this.Invoke(listBoxCallback, text); } else { listBox_freeDNS_Server.Items.Add(text); listBox_freeDNS_Server.SelectedIndex = listBox_freeDNS_Server.Items.Count - 1; listBox_freeDNS_Server.ClearSelected(); } }
C#需求:winform程序发送udp广播,并收到广播的机子回复消息?
问题:winform程序发送udp广播,收到广播的机子回复消息,接收回复的信息。 基本思路:创建一个UDPClient的实例,先开一个线程作为监听收到的信息,然后再发送广播。 但是却收不到回复信息。 或者有没有其他的思路?
通过udp发送hello world 信息
想要通过udp发送一个简单的信息,服务器部分在C#中执行: c#中的服务器代码: var server = new UdpClient(8585); var groupEP = new IPEndPoint(IPAddress.Parse("192.168.0.120"),8585); byte[] bytes = server.Receive(ref groupEP); 客户端的c# 部分: System.Net.Sockets.UdpClient client; client = new System.Net.Sockets.UdpClient("192.168.0.120",8585); client.Send(new byte[]{1,2,3,4},4); 如何在objective中实现相同的客服端?我在网上找了一些教程,包括我将其中一个数据库导入到工程中,不知道应该怎么实例化新对象,我试过这样: [[GCDAsyncUdpSocket alloc] initWithSocketQueue:... ??? I don't know how to initialize it. 非常感谢大家给我提供的帮助。谢谢
关于Android利用局域网进行UDP通信的问题
我写了一个小程序准备利用UDP和电脑之间进行通信,然后基于这个做一点东西,可是问题是我用AVD测试很好用的,但是用真机测试就是不行。 我的思路是让电脑和Android设备连接一台路由器,路由器为两台设备分配固定的ip地址进行通信。 拜托大家帮我看看啊,我这才是第一步就郁闷的要死 下面是代码。 1:MainActivity package com.company.zebork.testudpll; import android.app.Activity; import android.content.Context; import android.net.wifi.WifiManager; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; public class MainActivity extends Activity { EditText text; Button send; Handler handler; Message msg; EditText ad; String address; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); text = (EditText) findViewById(R.id.editText); send = (Button) findViewById(R.id.send); ad = (EditText) findViewById(R.id.editText2); handler = new Handler() { @Override public void handleMessage(Message msg) { text.setText(""); } }; /* send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { handler.handleMessage(msg); } });*/ send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { System.out.println(ad.getText().toString()); AsyncTask<String ,String , Void> toSend = new AsyncTask<String, String, Void>() { @Override protected Void doInBackground(String... params) { address = ad.getText().toString(); UDPClient client = new UDPClient(address); System.out.println("here" + address); client.send(text.getText().toString()); msg = new Message(); handler.sendMessage(msg); return null; } @Override protected void onPostExecute(Void aVoid) { super.onPostExecute(aVoid); } }.execute(address); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } } 2、UDPClient package com.company.zebork.testudpll; import java.io.IOException; import java.net.*; public class UDPClient { private DatagramPacket dp; private DatagramSocket ds; private byte[] buf; private String address; public UDPClient(String address) { buf = new byte[4096]; this.address = address; System.out.println("??" + address); try { ds = new DatagramSocket(8888); } catch (SocketException e) { e.printStackTrace(); } } public void send(String str) { buf = str.getBytes(); try { dp = new DatagramPacket(buf, buf.length,new InetSocketAddress(address,5679)); ds.send(dp); ds.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } 3、AndroidManifest【有些权限我都没有用到,因为调试这个错误才加上的】 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.zebork.testudpll" > <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 4、activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity" android:orientation="vertical"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/editText" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" /> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/editText2" android:layout_gravity="center_horizontal" android:text="ip" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="发送" android:id="@+id/send" android:layout_centerVertical="true" android:layout_centerHorizontal="true" android:layout_gravity="center_horizontal" /> </LinearLayout> 5、服务器的Java文件,我是用JavaSE写的,因为不会javaEE import java.io.IOException; import java.net.*; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class TestUDPClient extends Frame{ private static DatagramPacket dp; private static DatagramSocket ds; private static TextField text; private static TextArea ta; public static void main(String[] args) { Frame f = new TestUDPClient(); f.setLocation(200, 200); f.setSize(300,200); f.setVisible(true); text = new TextField(); ta = new TextArea(); f.add(text,BorderLayout.SOUTH); f.add(ta,BorderLayout.CENTER); f.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { if(ds!=null) ds.close(); System.exit(0); } }); startServer(); } public static void startServer() { byte[] buf = new byte[4096]; dp = new DatagramPacket(buf,buf.length); try { ds = new DatagramSocket(5679); } catch (SocketException e) { e.printStackTrace(); } while(true) { try { ds.receive(dp); if(ta.getText().length() > 0) ta.setText(ta.getText() + "\n" + new String(buf,0,dp.getLength())); else ta.setText(new String(buf,0,dp.getLength())); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
udpclient的send方法,报“不允许对非连接的套接字执行此操作”
IPEndPoint ep=new IPEndPoint(IPAddress.any,5300); UdpClient client=new UdpClient(ep); client.send(data,8);
Android Mina框架是否支持UDPClient发送广播包?
如题,请问mina框架是否支持发送udp广播包,以下面代码发送,会提示服务器异常。 ``` // 创建一个tcp/ip 连接 //创建客户端连接器 Log.i("TAG","正在创建Socket连接!"); Log.i("TAG","PORT:"+PORT+",HostName:"+hostName); NioDatagramConnector connector=new NioDatagramConnector(); /*---------接收字符串---------*/ // //创建接收数据的过滤器 DefaultIoFilterChainBuilder chain = connector.getFilterChain(); // 设定这个过滤器将一行一行(/r/n)的读取数据 //chain.addLast("myChin", new ProtocolCodecFilter( // new TextLineCodecFactory())); /*---------接收对象---------*/ // 创建接收数据的过滤器 // 创建接收数据的过滤器 chain.addLast("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8") //, //LineDelimiter.WINDOWS.getValue(), //LineDelimiter.WINDOWS.getValue() ))); //设置日志记录器 //chain.addLast("Logger", new LoggingFilter()); //设置连接超时检查时间 connector.setConnectTimeoutCheckInterval(10000); //设置事件处理器 connector.setHandler(new ClientHandler(this.myHandler)); //建立连接 Log.i("TAG","开始建立连接!"); cf=connector.connect(new InetSocketAddress( hostName,PORT)); cf.addListener(new IoFutureListener(){ @Override public void operationComplete(IoFuture future) { // TODO Auto-generated method stub ConnectFuture connFuture = (ConnectFuture) future; if (connFuture.isConnected()) { session = future.getSession(); try { sendData(); } catch (InterruptedException e) { e.printStackTrace(); } } else { Log.i("TAG","not connect"); } } }); ``` 其中hostname是“255.255.255.255”,port是9999
请大神帮我看下这部分代码怎么写?谢谢!很急
如图所示,我把基本通讯功能已经实现,但是我想实现下图中红色圈中部分的功能,自动发送跟数据格式的功能怎么实现啊,希望发送端跟接收端都可以实现这个数据格式的功能,谢谢![图片说明](https://img-ask.csdn.net/upload/201510/08/1444312460_795190.png) 整体代码如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; //添加的命名空间引用 using System.Net; using System.Net.Sockets; using System.Threading; namespace UDP_扩展开发 { public partial class UDPTOOL : Form { delegate void AddListBoxItemCallback(string text); AddListBoxItemCallback listBoxCallback; //使用的接收端口号 private int port = 8001; private UdpClient udpClient; public UDPTOOL() { InitializeComponent(); listBoxCallback = new AddListBoxItemCallback(AddListBoxItem); } private void AddListBoxItem(string text) { //如果listBoxReceive被不同的线程访问则通过委托处理; if (listBoxReceive.InvokeRequired) { this.Invoke(listBoxCallback, text); } else { listBoxReceive.Items.Add(text); listBoxReceive.SelectedIndex = listBoxReceive.Items.Count - 1; } } /// <summary> /// 在后台运行的接收线程 /// </summary> private void ReceiveData() { //在本机指定的端口接收 udpClient = new UdpClient(port); IPEndPoint remote = null; //接收从远程主机发送过来的信息; while (true) { try { //关闭udpClient时此句会产生异常 byte[] bytes = udpClient.Receive(ref remote); string str = Encoding.UTF8.GetString(bytes, 0, bytes.Length); AddListBoxItem(string.Format("来自{0}:{1}", remote, str)); } catch { //退出循环,结束线程 break; } } } /// <summary> /// 发送数据到远程主机 /// </summary> private void sendData() { UdpClient myUdpClient = new UdpClient(); IPAddress remoteIP; if (IPAddress.TryParse(textBoxRemoteIP.Text, out remoteIP) == false) { MessageBox.Show("远程IP格式不正确"); return; } IPEndPoint iep = new IPEndPoint(remoteIP, port); byte[] bytes = System.Text.Encoding.UTF8.GetBytes(textBoxSend.Text); try { myUdpClient.Send(bytes, bytes.Length, iep); myUdpClient.Close(); textBoxSend.Focus(); } catch (Exception err) { MessageBox.Show(err.Message, "发送失败"); } finally { myUdpClient.Close(); } } private void UDPTOOL_Load(object sender, System.EventArgs e) { //设置listBox样式 listBoxReceive.HorizontalScrollbar = true; listBoxReceive.Dock = DockStyle.Fill; //获取本机第一个可用IP地址 IPAddress myIP = (IPAddress)Dns.GetHostAddresses(Dns.GetHostName()).GetValue(0); //为了在同一台机器调试,此IP也作为默认远程IP textBoxRemoteIP.Text = myIP.ToString(); //创建一个线程接收远程主机发来的信息 Thread myThread = new Thread(new ThreadStart(ReceiveData)); //将线程设为后台运行 myThread.IsBackground = true; myThread.Start(); textBoxSend.Focus(); } /// <summary> /// 单击发送按钮触发的事件 /// </summary> private void buttonSend_Click(object sender, System.EventArgs e) { { sendData(); } } /// <summary> /// 在textBoxSend中按下并释放Enter键后触发的事件 /// </summary> private void textBoxData_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == (char)Keys.Enter) sendData(); } private void UDPTOOL_FormClosing(object sender, FormClosingEventArgs e) { udpClient.Close(); } } } 如果有大神愿意帮忙可留下自己的qq,我会及时主动加上的,谢谢!
C#udpclient.send()
请帮忙看下,通过send如何发送数据![图片](https://img-ask.csdn.net/upload/201511/19/1447920329_109535.jpg)
JAVA UDP协议对接C#服务器 编码方式为unicode
![图片说明](https://img-ask.csdn.net/upload/201805/27/1527390334_516365.png) ![图片说明](https://img-ask.csdn.net/upload/201805/27/1527390372_218048.png) 上面图片使用测试工具实现效果。 JAVA代码无法实现,之前可以传输来着。一觉醒了居然不行了,捣鼓一晚上。 ``` package zyb.org.UDP; import java.io.IOException; import java.io.InterruptedIOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class UDPClient { private static final int TIMEOUT = 5000; //设置接收数据的超时时间 private static final int MAXNUM = 5; //设置重发数据的最多次数 public static void main(String args[])throws IOException{ String str_send = "Cmd=Close,Para=1|Left,EndPoint=192.168.8.102:11001"; String unicode_Str = gbEncoding(str_send); byte[] buf = new byte[1024]; //客户端在9000端口监听接收到的数据 DatagramSocket ds = new DatagramSocket(11001); InetAddress loc = InetAddress.getLocalHost(); //定义用来发送数据的DatagramPacket实例 DatagramPacket dp_send= new DatagramPacket(unicode_Str.getBytes(),unicode_Str.length(),loc,11003); //定义用来接收数据的DatagramPacket实例 DatagramPacket dp_receive = new DatagramPacket(buf, 1024); //数据发向本地3000端口 ds.setSoTimeout(TIMEOUT); //设置接收数据时阻塞的最长时间 int tries = 0; //重发数据的次数 boolean receivedResponse = false; //是否接收到数据的标志位 //直到接收到数据,或者重发次数达到预定值,则退出循环 while(!receivedResponse && tries<MAXNUM){ //发送数据 ds.send(dp_send); try{ //接收从服务端发送回来的数据 ds.receive(dp_receive); //如果接收到的数据不是来自目标地址,则抛出异常 if(!dp_receive.getAddress().equals(loc)){ throw new IOException("Received packet from an umknown source"); } //如果接收到数据。则将receivedResponse标志位改为true,从而退出循环 receivedResponse = true; }catch(InterruptedIOException e){ //如果接收数据时阻塞超时,重发并减少一次重发的次数 tries += 1; System.out.println("Time out," + (MAXNUM - tries) + " more tries..." ); } } if(receivedResponse){ //如果收到数据,则打印出来 System.out.println("client received data from server:"); String str_receive = new String(dp_receive.getData(),0,dp_receive.getLength()) + " from " + dp_receive.getAddress().getHostAddress() + ":" + dp_receive.getPort(); System.out.println(str_receive); //由于dp_receive在接收了数据之后,其内部消息长度值会变为实际接收的消息的字节数, //所以这里要将dp_receive的内部消息长度重新置为1024 dp_receive.setLength(1024); }else{ //如果重发MAXNUM次数据后,仍未获得服务器发送回来的数据,则打印如下信息 System.out.println("No response -- give up."); } ds.close(); } /* * 中文转unicode编码 */ public static String gbEncoding(final String gbString) { char[] utfBytes = gbString.toCharArray(); String unicodeBytes = ""; for (int i = 0; i < utfBytes.length; i++) { String hexB = Integer.toHexString(utfBytes[i]); if (hexB.length() <= 2) { hexB = "00" + hexB; } unicodeBytes = unicodeBytes + "\\u" + hexB; } return unicodeBytes; } /* * unicode编码转中文 */ public static String decodeUnicode(final String dataStr) { int start = 0; int end = 0; final StringBuffer buffer = new StringBuffer(); while (start > -1) { end = dataStr.indexOf("\\u", start + 2); String charStr = ""; if (end == -1) { charStr = dataStr.substring(start + 2, dataStr.length()); } else { charStr = dataStr.substring(start + 2, end); } char letter = (char) Integer.parseInt(charStr, 16); // 16进制parse整形字符串。 buffer.append(new Character(letter).toString()); start = end; } return buffer.toString(); } } ```
UDP给指定IP和端口传输数据包,为什么一直显示Network is unreachable: Datagram send failed
**_ UDPClient.java** package com.bill.udp.client; import java.io.IOException; import java.io.RandomAccessFile; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.InetSocketAddress; import com.bill.udp.util.UDPUtils; public class UDPClient { private static final String SEND_FILE_PATH = "D:/imgmap.jpg"; public static void main(String[] args){ long startTime = System.currentTimeMillis(); byte[] buf = new byte[UDPUtils.BUFFER_SIZE]; byte[] receiveBuf = new byte[1]; RandomAccessFile accessFile = null; DatagramPacket dpk = null; DatagramSocket dsk = null; int readSize = -1; try { accessFile = new RandomAccessFile(SEND_FILE_PATH,"r"); //构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。 dpk = new DatagramPacket(buf, buf.length,new InetSocketAddress(InetAddress.getByName("192.168.1.106"), 5000)); //创建数据报套接字,将其绑定到指定的本地地址。 dsk = new DatagramSocket(5001, InetAddress.getByName("192.168.1.106")); int sendCount = 0; while((readSize = accessFile.read(buf,0,buf.length)) != -1){ dpk.setData(buf, 0, readSize); dsk.send(dpk); // wait server response { while(true){ dpk.setData(receiveBuf, 0, receiveBuf.length); dsk.receive(dpk); // confirm server receive if(!UDPUtils.isEqualsByteArray(UDPUtils.successData,receiveBuf,dpk.getLength())){ System.out.println("resend ..."); dpk.setData(buf, 0, readSize); dsk.send(dpk); }else break; } } System.out.println("send count of "+(++sendCount)+"!"); } // send exit wait server response while(true){ System.out.println("client send exit message ...."); dpk.setData(UDPUtils.exitData,0,UDPUtils.exitData.length); dsk.send(dpk); dpk.setData(receiveBuf,0,receiveBuf.length); dsk.receive(dpk); if(!UDPUtils.isEqualsByteArray(UDPUtils.exitData, receiveBuf, dpk.getLength())){ System.out.println("client Resend exit message ...."); dsk.send(dpk); }else break; } }catch (Exception e) { e.printStackTrace(); } finally{ try { if(accessFile != null) accessFile.close(); if(dsk != null) dsk.close(); } catch (IOException e) { e.printStackTrace(); } } long endTime = System.currentTimeMillis(); System.out.println("time:"+(endTime - startTime)); } } **UDPUtils.java** package com.bill.udp.util; public class UDPUtils { private UDPUtils(){} /** transfer file byte buffer **/ public static final int BUFFER_SIZE = 50 * 1024; /** controller port **/ public static final int PORT = 50000; /** mark transfer success **/ public static final byte[] successData = "success data mark".getBytes(); /** mark transfer exit **/ public static final byte[] exitData = "exit data mark".getBytes(); public static void main(String[] args) { byte[] b = new byte[]{1}; System.out.println(isEqualsByteArray(successData,b)); } public static boolean isEqualsByteArray(byte[] compareBuf,byte[] buf){ if (buf == null || buf.length == 0) return false; boolean flag = true; if(buf.length == compareBuf.length){ for (int i = 0; i < buf.length; i++) { if(buf[i] != compareBuf[i]){ flag = false; break; } } }else return false; return flag; } public static boolean isEqualsByteArray(byte[] compareBuf,byte[] buf,int len){ if (buf == null || buf.length == 0 || buf.length < len || compareBuf.length < len) return false; boolean flag = true; int innerMinLen = Math.min(compareBuf.length, len); for (int i = 0; i < innerMinLen; i++) { if(buf[i] != compareBuf[i]){ flag = false; break; } } return flag; } }
C# 无法触发窗口弹出 show方法不生效
要做一个基于UDP的群聊加私聊程序,群聊已经实现了,私聊也已经单独实现了,但是我想让着两个窗体有联系,就想QQ一样,PC1发消息的时候,PC2 自动弹出消息窗口。 登录窗体: using System.Net; namespace NetMeetingExample { public partial class FormLogin : Form { public FormLogin() { InitializeComponent(); } private void Login_Load(object sender, EventArgs e) { this.textBox1.Text = Dns.GetHostName().ToString(); } public static string nicheng; public static string group; private void button1_Click(object sender, EventArgs e) { nicheng = textBox1.Text; group =comboBox1.Text; //this.Opacity = 0; this.DialogResult = DialogResult.OK; } private void button2_Click(object sender, EventArgs e) { this.DialogResult = DialogResult.Cancel; } } } 群聊窗体: using System.Net; using System.Net.Sockets; using System.Threading; namespace NetMeetingExample { public partial class FormMeeting : Form { private enum ListBoxOperation { AddItem, RemoveItem }; private delegate void SetListBoxItemCallback( ListBox listbox, string text, ListBoxOperation operation); SetListBoxItemCallback listBoxCallback; //使用的IP地址 private IPAddress broderCastIp = IPAddress.Parse("224.100.0.1"); //使用的接收端口号 public static int port = 8001; private UdpClient udpClient; public FormMeeting() { if (FormLogin.group=="101021") { broderCastIp = IPAddress.Parse("224.100.0.1"); } if (FormLogin.group == "101022") { broderCastIp = IPAddress.Parse("224.100.0.2"); } if (FormLogin.group == "101023") { broderCastIp = IPAddress.Parse("224.100.0.3"); } if (FormLogin.group == "101024") { broderCastIp = IPAddress.Parse("224.100.0.4"); } InitializeComponent(); listBoxCallback = new SetListBoxItemCallback(SetListBoxItem); this.Text = FormLogin.group; } private void SetListBoxItem(ListBox listbox, string text, ListBoxOperation operation) { string[] cc;//= splitString[1].Split('@'); if (listbox.InvokeRequired == true) { this.Invoke(listBoxCallback, listbox, text, operation); } else { if (operation == ListBoxOperation.AddItem) { if (listbox == listBoxAddress) { if (listbox.Items.Contains(text) == false) if (text != "") { { cc=text.Split('@'); string oo = cc[0]; listBoxMessage.Items.Add(oo+"进入。"); listbox.Items.Add(text); } } } else { if (text != "[]进入。") { listbox.Items.Add(text); // SetListBoxItem(listBoxMessage, // string.Format("[{0}]进入。",cc[0]), ListBoxOperation.AddItem); } } listbox.SelectedIndex = listbox.Items.Count - 1; listbox.ClearSelected(); } else if (operation == ListBoxOperation.RemoveItem) { cc = text.Split('@'); // SetListBoxItem(listBoxMessage, // string.Format("[{0}]退出。", cc[0]), ListBoxOperation.AddItem); // // listBoxMessage.Items.Add(string.Format("[{0}]退出。", cc[0])); string oo = cc[0]; listBoxMessage.Items.Add(oo+"退出。"); listbox.Items.Remove(text); } } } public static void SendMessage(IPAddress ip, string sendString) { UdpClient myUdpClient = new UdpClient(); //允许发送和接收广播数据报 // myUdpClient.EnableBroadcast = true; //必须使用组播地址范围内的地址 IPEndPoint iep = new IPEndPoint(ip, port); //将发送内容转换为字节数组 byte[] bytes = System.Text.Encoding.UTF8.GetBytes(sendString); try { //向子网发送信息 myUdpClient.Send(bytes, bytes.Length, iep); } catch (Exception err) { MessageBox.Show(err.Message, "发送失败"); } finally { myUdpClient.Close(); } } public static IPAddress ipp; private void FormMeeting_Load(object sender, EventArgs e) { listBoxMessage.HorizontalScrollbar = true; buttonLogin.Enabled = true; buttonLogout.Enabled = false; groupBoxRoom.Enabled = false; IPAddress[] iph = Dns.GetHostAddresses(Dns.GetHostName()); ipp = iph[iph.Length-2]; } /// <summary> /// 接收线程 /// </summary> private void ReceiveMessage() { udpClient = new UdpClient(port); //必须使用组播地址范围内的地址 udpClient.JoinMulticastGroup(broderCastIp); udpClient.Ttl = 50; IPEndPoint remote = null; while (true) { try { //关闭udpClient时此句会产生异常 byte[] bytes = udpClient.Receive(ref remote); string str = Encoding.UTF8.GetString(bytes, 0, bytes.Length); string[] splitString = str.Split(','); int s = splitString[0].Length; //string[] splithostname; // splithostname= splitString[1].Split('@'); string[] mhost; mhost = splitString[1].Split('@'); switch (splitString[0]) { case "Login": //进入会议室 // SetListBoxItem(listBoxMessage, // string.Format("[{0}]进入。", splithostname[0]), ListBoxOperation.AddItem); SetListBoxItem(listBoxAddress, splitString[1], ListBoxOperation.AddItem); string userListString = "List," ; for (int i = 0; i < listBoxAddress.Items.Count; i++) { userListString += "," + listBoxAddress.Items[i].ToString(); } SendMessage(remote.Address, userListString); break; case "List": //参加会议人员名单 for (int i = 1; i < splitString.Length; i++) { SetListBoxItem(listBoxAddress, splitString[i], ListBoxOperation.AddItem); // SetListBoxItem(listBoxMessage, // string.Format("[{0}]进入。", splithostname[0]), ListBoxOperation.AddItem); } break; case "Message": //发言内容 SetListBoxItem(listBoxMessage, string.Format("[{0}]说:{1}", mhost[0], mhost[1]), ListBoxOperation.AddItem); break; case "Logout": //退出会议室 // SetListBoxItem(listBoxMessage, // string.Format("[{0}]退出。", FormLogin.nicheng), // ListBoxOperation.AddItem); // SetListBoxItem(listBoxMessage, // string.Format("[{0}]退出。", splithostname[0]), ListBoxOperation.AddItem); SetListBoxItem(listBoxAddress, FormLogin.nicheng + "@" + remote.Address.ToString(), ListBoxOperation.RemoveItem); break; case "mi": FormChat fc = new FormChat(); fc.Owner = this; fc.Show(); // MessageBox.Show("sfs"); break; } } catch { //退出循环,结束线程 break; } } } private void textBoxMessage_KeyPress(object sender, KeyPressEventArgs e) { if (e.KeyChar == (char)Keys.Return) { if (textBoxMessage.Text.Trim().Length > 0) { SendMessage(broderCastIp, "Message," + FormLogin.nicheng+"@"+ textBoxMessage.Text); textBoxMessage.Text = ""; } } } //窗体已关闭并指定关闭原因前触发的事件 private void Form1_FormClosing(object sender, FormClosingEventArgs e) { if (buttonLogout.Enabled == true) { MessageBox.Show("请先离开会议室,然后再退出!", "", MessageBoxButtons.OK, MessageBoxIcon.Warning); //不关闭窗体 e.Cancel = true; } } //单击进入会议室按钮触发的事件 private void buttonLogin_Click(object sender, EventArgs e) { Cursor.Current = Cursors.WaitCursor; Thread myThread = new Thread(ReceiveMessage); myThread.Start(); //等待接收线程准备完毕 Thread.Sleep(1000); SendMessage(broderCastIp, "Login,"); buttonLogin.Enabled = false; buttonLogout.Enabled = true; groupBoxRoom.Enabled = true; // SetListBoxItem(listBoxMessage, // string.Format("[{0}]进入。", FormLogin.nicheng), ListBoxOperation.AddItem); SetListBoxItem(listBoxAddress, FormLogin.nicheng + "@" +ipp.ToString(), ListBoxOperation.AddItem); string userListString = "List," + FormLogin.nicheng + "@" + ipp.ToString(); SendMessage(broderCastIp , userListString); Cursor.Current = Cursors.Default; } //单击退出会议室按钮触发的事件 private void buttonLogout_Click(object sender, EventArgs e) { Cursor.Current = Cursors.WaitCursor; SendMessage(broderCastIp, "Logout,"); udpClient.DropMulticastGroup(this.broderCastIp); //等待接收线程处理完毕 Thread.Sleep(1000); //结束接收线程 udpClient.Close(); buttonLogin.Enabled = true; buttonLogout.Enabled = false; groupBoxRoom.Enabled = false; Cursor.Current = Cursors.Default; } private void button1_Click(object sender, EventArgs e) { // string add = "sdfsdf-192.168.22.3"; //string[] omg = add.Split('@'); // MessageBox.Show(omg[1].ToString()); //FormChat FC = new FormChat(); // FC.Owner = this; // FC.Show(); } public static string[] omg; private void listBoxAddress_MouseDoubleClick(object sender, MouseEventArgs e) { string add = listBoxAddress.SelectedItem.ToString(); omg = add.Split('@'); FormChat fc = new FormChat(); fc.Owner = this; fc.Show(); } } } 私聊窗体 using System.Net; using System.Net.Sockets; using System.Threading; namespace NetMeetingExample { public partial class FormChat : Form { /// <summary>接收用</summary> private UdpClient receiveUdpClient; /// <summary>发送用</summary> private UdpClient sendUdpClient; /// <summary>和本机绑定的端口号</summary> private const int port = 18001; /// <summary>本机IP</summary> IPAddress ip; /// <summary>远程主机IP</summary> IPAddress remoteIp; public FormChat() { InitializeComponent(); IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName()); ip = ips[ips.Length - 1]; //为了在同一台机器调试,此IP也作为默认远程IP // remoteIp = ip; remoteIp = IPAddress.Parse(FormMeeting.omg[1]); textBoxRemoteIP.Text = FormMeeting.omg[1]; textBoxSend.Text = "你好!"; } private void buttonSend_Click(object sender, EventArgs e) { Thread t = new Thread(SendMessage); t.IsBackground = true; t.Start(textBoxSend.Text); } private void FormChat_Load(object sender, EventArgs e) { //创建一个线程接收远程主机发来的信息 Thread myThread = new Thread(ReceiveData); //将线程设为后台运行 myThread.IsBackground = true; myThread.Start(); textBoxSend.Focus(); } private void SendMessage(object obj) { string message = (string)obj; sendUdpClient = new UdpClient(0); byte[] bytes = System.Text.Encoding.Unicode.GetBytes(message); IPEndPoint iep = new IPEndPoint(remoteIp, port); try { sendUdpClient.Send(bytes, bytes.Length, iep); AddItem(listBoxStatus, string.Format("向{0}发送:{1}", iep, message)); ClearTextBox(); } catch (Exception ex) { AddItem(listBoxStatus, "发送出错:" + ex.Message); } } private void ReceiveData() { IPEndPoint local = new IPEndPoint(ip, port); receiveUdpClient = new UdpClient(local); IPEndPoint remote = new IPEndPoint(IPAddress.Any, 0); while (true) { try { //关闭udpClient时此句会产生异常 byte[] receiveBytes = receiveUdpClient.Receive(ref remote); string receiveMessage = Encoding.Unicode.GetString( receiveBytes, 0, receiveBytes.Length); AddItem(listBoxReceive, string.Format("来自{0}:{1}", remote, receiveMessage)); } catch { break; } } } delegate void AddListBoxItemDelegate(ListBox listbox, string text); private void AddItem(ListBox listbox, string text) { if (listbox.InvokeRequired) { AddListBoxItemDelegate d = AddItem; listbox.Invoke(d, new object[] { listbox, text }); } else { listbox.Items.Add(text); listbox.SelectedIndex = listbox.Items.Count - 1; listbox.ClearSelected(); } } delegate void ClearTextBoxDelegate(); private void ClearTextBox() { if (textBoxSend.InvokeRequired) { ClearTextBoxDelegate d = ClearTextBox; textBoxSend.Invoke(d); } else { textBoxSend.Clear(); textBoxSend.Focus(); } } private void button1_Click(object sender, EventArgs e) { FormMeeting.SendMessage(remoteIp, "mi," + "hello~"); // SendMessage(broderCastIp, "Message," + textBoxMessage.Text); } } } Program.cs static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); FormLogin fl = new FormLogin(); if (fl.ShowDialog() == DialogResult.OK) { Application.Run(new FormMeeting()); } else { Application.Exit(); } 在私聊窗体里单击BUTTON1会向对端发送“mi”命令从而触发对端的窗体弹出,函数能进去,但窗体就是不弹出,另外将弹出写在button_click下,然后在mi下执行button的_click事件也不能触发,,但是单独单击却能打开,函数是能进来的 求高人解决。。。。。。。。。。
C语言UDP SOCKET编程求助
本人初入计算机网络,最近在编写一个简单的UDP模型,主要功能是1.Server先开启监听 2.Client用sendto发送一条信息 3.Server用recvfrom接收 4.再用sendto回复 5.Client用recvfrom接收 参考了一些例子,但是从第四步开始总出错,ERRNO为97(#define EAFNOSUPPORT 97 /* Address family not supported by protocol */)在网上搜索无果,希望有经验的朋友们帮助一下我,十分谢谢!!! 我用C语言在UBUNTU18.10下实现。 以下是代码及运行结果: ``` UDPServer.c #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #define PORT 8004 //远端地址端口号 void main(void) { int serverSocket,peerlen,buflen; char buf[200]; struct sockaddr_in local_addr,addr_from; if(-1==(serverSocket=socket(AF_INET,SOCK_DGRAM,0))) puts("socket开启失败"); else puts("socket开启成功"); bzero(&local_addr, sizeof(local_addr));//清空字节 local_addr.sin_family = AF_INET; local_addr.sin_port = htons(PORT); local_addr.sin_addr.s_addr =INADDR_ANY;//s_addr到底是个什么类型? //inet_addr是一个计算机函数,功能是将一个点分十进制的IP //转换成一个长整数型数(u_long类型)等同于inet_addr()。 if(bind(serverSocket,(struct sockaddr*)&local_addr, sizeof(local_addr))==-1) printf("%s\n","绑定失败"); else printf("%s\n","绑定成功"); if(-1==(buflen=recvfrom(serverSocket,buf,strlen(buf),0,(struct sockaddr *)&addr_from,&peerlen))) puts("接受失败\n"); else puts("接受成功\n"); puts(buf); if(-1==(int)sendto(serverSocket,"REC",strlen("REC"),0, (struct sockaddr *)&addr_from,sizeof(addr_from))) puts("发送失败\n"); else puts("发送成功\n"); close(serverSocket); printf("%d",errno); } UDPClient.c #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #define PORT 8004 //远端地址端口号 void main(void) { int clientSocket,buflen,addrlen,peerlen; char addr[]="10.14.21.68",buf[200]; struct sockaddr_in remoteaddr,addr_from; if(-1==(clientSocket=socket(AF_INET,SOCK_DGRAM,0))) puts("socket开启失败"); else puts("socket开启成功"); bzero(&remoteaddr, sizeof(remoteaddr));//清空字节 remoteaddr.sin_family = AF_INET; remoteaddr.sin_port = htons(PORT); remoteaddr.sin_addr.s_addr =inet_addr(addr); if(-1==(sendto(clientSocket,"HI",strlen("HI"),0, (struct sockaddr *)&remoteaddr,addrlen=sizeof(remoteaddr)))) puts("发送失败\n"); else puts("发送成功\n"); if(-1==(buflen=recvfrom(clientSocket,buf,sizeof(buf),0, (struct sockaddr *)&remoteaddr,&addrlen))) puts("接受失败\n"); else puts("接受成功\n"); puts(buf); close(clientSocket); } 运行结果 Server: socket开启成功 绑定成功 接受成功 HI3Z� 发送失败 97 Client: socket开启成功 发送成功 ```
Python 调用C++ dll库文件函数提示WindowsError: exception: access violation writing 0x00905A4D
.H文件如下: /* 视频解码 */ #ifndef __BLL_AUTELVIDEODECODE_H #define __BLL_AUTELVIDEODECODE_H #ifdef AUTELVIDEODECODE_EXPORTS #define AUTELVIDEODECODE_API __declspec(dllexport) #else #define AUTELVIDEODECODE_API __declspec(dllimport) #endif #include "bll/UDPClient/UDPAsyncClient.h" #include "bll/DataManager/DataManager.h" #include "bll/Utils/CommonFuntion.h" #include "bll/frame.h" #include "bll/video_data_mgn.h" #include "bll/h264.h" extern "C" { //编码 #include "libavcodec/avcodec.h" //封装格式处理 #include "libavformat/avformat.h" //像素处理 #include "libswscale/swscale.h" #include "libavutil/avutil.h" #include "libavutil/imgutils.h" }; #pragma comment(lib,"avutil.lib") #pragma comment(lib,"avformat.lib") #pragma comment(lib,"avcodec.lib") #pragma comment(lib,"swscale.lib") #define VIDEO_UDP_PORT (1234) #define min(a, b) ((a) < (b) ? (a) : (b)) #define MAX_RECVBUF_SIZE (64 * 1024) #define MAX_FRAME_SIZE (1024 * 1024) #pragma pack(push, 1) struct Decoder { AVCodec *codec; AVFrame *frame; AVCodecContext *dec_ctx; }; typedef struct { uint8_t *data; int size; int64_t pts; int keyframe; int decode_only; } VideoPacket; typedef struct { int width; int height; int64_t pts; int keyframe; int decode_only; int opaque; uint8_t *data; int size; } YuvFrame; #pragma pack(pop) typedef void (WINAPIV *yuvFrame_func)(YuvFrame *yuv); class AUTELVIDEODECODE_API CAutelVideoDecode { public: explicit CAutelVideoDecode(std::string strHost="", int nPort=VIDEO_UDP_PORT); ~CAutelVideoDecode(void); inline void SetYuvframeCallback(yuvFrame_func pfn) { m_pfnyuvFrame = pfn; } //functions private: //通过udp实时获取视频数据包线程 void StartRecvPacketThread(); void StopRecvPacketThread(); static int WINAPIV recv_video_data_func(char* buf, int length, void* ctx, void* pObj); void DoRecvPacket(); static DWORD ThRecvPacket(LPVOID lpParam); //从buf里面读取视频帧数据进行渲染线程 void StartRenderThread(); void StopRenderThread(); void DoRenderFrame(); static DWORD ThRenderFrame(LPVOID lpParam); Decoder *Decoder_Create(void); int Decoder_Destroy(); int Decoder_Decode(VideoPacket *inpkt, YuvFrame *frame); int get_video_frame(AVFrame *frame, YuvFrame *yuv); void PushFrame(YuvFrame frame); YuvFrame FrontFrame(); //params private: //通过udp实时获取视频数据包线程 HANDLE m_hRecvVideoPacket; bool m_bStopRecvVideoPacket; //从buf里面读取视频帧数据进行渲染线程 HANDLE m_hRenderFrame; bool m_bStopRender; CUDPAsyncClient *m_pUdpClient; std::string m_strHostAddr; int m_udpPort; Decoder *m_pDecoder; yuvFrame_func m_pfnyuvFrame; typedef std::queue<YuvFrame> QUEUE_YUVFRAME; QUEUE_YUVFRAME m_que_yuvframe; CRITICAL_SECTION m_cri_yuvFramequeLocker; }; #endif CPP文件 // dllmain.cpp : Defines the entry point for the DLL application. #include "stdafx.h" #include "AutelVideoDecode.h" BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } extern "C" { AUTELVIDEODECODE_API CAutelVideoDecode* AutelVideoDecode() { return new CAutelVideoDecode(); } AUTELVIDEODECODE_API void SetYuvframeCallback(CAutelVideoDecode* pAutel, yuvFrame_func pfn) { pAutel->SetYuvframeCallback(pfn); } } #####编译成AutelVideoDecode.dll库后供python2.7程序调用。 ####Python程序如下 import sys,pygame import YUVFrame import thread from ctypes import * ObjAutelvideodecodeDLL = windll.LoadLibrary(".\\bin\\autelvideodecode.dll") class AutoTestAutelRealTimeVideo: def __init__(self): pygame.init() self.size = width, height = 1280, 720 self.black = 0, 0, 0 self.YUVFrame = None self.overlay =None self.IYUV = pygame.IYUV_OVERLAY self.lock = thread.allocate_lock() CALLFUCTION = CFUNCTYPE(None, POINTER(YUVFrame.YUVFrame)) self.PrenderYuvframe = CALLFUCTION(self.renderYuvframe) #ObjAutelvideodecodeDLL.AutelVideoDecode.argtype=c_char_p ObjAutelvideodecodeDLL.AutelVideoDecode.restype = c_void_p ObjAutelvideodecodeDLL.SetYuvframeCallback.argtypes = (c_void_p,c_void_p) #ObjAutelvideodecodeDLL.SetYuvframeCallback.restype = None self.AutelObj = ObjAutelvideodecodeDLL.AutelVideoDecode() def ...... 编译后出错: Connected to pydev debugger (build 129.782) Traceback (most recent call last): File "C:\Program Files (x86)\JetBrains\PyCharm 2.7.3\helpers\pydev\pydevd.py", line 1481, in <module> debugger.run(setup['file'], None, None) File "C:\Program Files (x86)\JetBrains\PyCharm 2.7.3\helpers\pydev\pydevd.py", line 1124, in run pydev_imports.execfile(file, globals, locals) #execute the script File "E:/AutoTestAutelRealTimeVideo/AutoTestAutelRealTimeVideo.py", line 84, in <module> test() File "E:/AutoTestAutelRealTimeVideo/AutoTestAutelRealTimeVideo.py", line 66, in test test = AutoTestAutelRealTimeVideo() File "E:/AutoTestAutelRealTimeVideo/AutoTestAutelRealTimeVideo.py", line 25, in __init__ self.AutelObj = ObjAutelvideodecodeDLL.AutelVideoDecode() WindowsError: exception: access violation writing 0x00905A4D
相见恨晚的超实用网站
搞学习 知乎:www.zhihu.com 简答题:http://www.jiandati.com/ 网易公开课:https://open.163.com/ted/ 网易云课堂:https://study.163.com/ 中国大学MOOC:www.icourse163.org 网易云课堂:study.163.com 哔哩哔哩弹幕网:www.bilibili.com 我要自学网:www.51zxw
花了20分钟,给女朋友们写了一个web版群聊程序
参考博客 [1]https://www.byteslounge.com/tutorials/java-ee-html5-websocket-example
爬虫福利二 之 妹子图网MM批量下载
爬虫福利一:27报网MM批量下载    点击 看了本文,相信大家对爬虫一定会产生强烈的兴趣,激励自己去学习爬虫,在这里提前祝:大家学有所成! 目标网站:妹子图网 环境:Python3.x 相关第三方模块:requests、beautifulsoup4 Re:各位在测试时只需要将代码里的变量 path 指定为你当前系统要保存的路径,使用 python xxx.py 或IDE运行即可。
字节跳动视频编解码面经
引言 本文主要是记录一下面试字节跳动的经历。 三四月份投了字节跳动的实习(图形图像岗位),然后hr打电话过来问了一下会不会opengl,c++,shador,当时只会一点c++,其他两个都不会,也就直接被拒了。 七月初内推了字节跳动的提前批,因为内推没有具体的岗位,hr又打电话问要不要考虑一下图形图像岗,我说实习投过这个岗位不合适,不会opengl和shador,然后hr就说秋招更看重基础。我当时
Java学习的正确打开方式
在博主认为,对于入门级学习java的最佳学习方法莫过于视频+博客+书籍+总结,前三者博主将淋漓尽致地挥毫于这篇博客文章中,至于总结在于个人,实际上越到后面你会发现学习的最好方式就是阅读参考官方文档其次就是国内的书籍,博客次之,这又是一个层次了,这里暂时不提后面再谈。博主将为各位入门java保驾护航,各位只管冲鸭!!!上天是公平的,只要不辜负时间,时间自然不会辜负你。 何谓学习?博主所理解的学习,它
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过
大学四年自学走来,这些私藏的实用工具/学习网站我贡献出来了
大学四年,看课本是不可能一直看课本的了,对于学习,特别是自学,善于搜索网上的一些资源来辅助,还是非常有必要的,下面我就把这几年私藏的各种资源,网站贡献出来给你们。主要有:电子书搜索、实用工具、在线视频学习网站、非视频学习网站、软件下载、面试/求职必备网站。 注意:文中提到的所有资源,文末我都给你整理好了,你们只管拿去,如果觉得不错,转发、分享就是最大的支持了。 一、电子书搜索 对于大部分程序员...
linux系列之常用运维命令整理笔录
本博客记录工作中需要的linux运维命令,大学时候开始接触linux,会一些基本操作,可是都没有整理起来,加上是做开发,不做运维,有些命令忘记了,所以现在整理成博客,当然vi,文件操作等就不介绍了,慢慢积累一些其它拓展的命令,博客不定时更新 顺便拉下票,我在参加csdn博客之星竞选,欢迎投票支持,每个QQ或者微信每天都可以投5票,扫二维码即可,http://m234140.nofollow.ax.
比特币原理详解
一、什么是比特币 比特币是一种电子货币,是一种基于密码学的货币,在2008年11月1日由中本聪发表比特币白皮书,文中提出了一种去中心化的电子记账系统,我们平时的电子现金是银行来记账,因为银行的背后是国家信用。去中心化电子记账系统是参与者共同记账。比特币可以防止主权危机、信用风险。其好处不多做赘述,这一层面介绍的文章很多,本文主要从更深层的技术原理角度进行介绍。 二、问题引入 假设现有4个人...
Python 基础(一):入门必备知识
目录1 标识符2 关键字3 引号4 编码5 输入输出6 缩进7 多行8 注释9 数据类型10 运算符10.1 常用运算符10.2 运算符优先级 1 标识符 标识符是编程时使用的名字,用于给变量、函数、语句块等命名,Python 中标识符由字母、数字、下划线组成,不能以数字开头,区分大小写。 以下划线开头的标识符有特殊含义,单下划线开头的标识符,如:_xxx ,表示不能直接访问的类属性,需通过类提供
这30个CSS选择器,你必须熟记(上)
关注前端达人,与你共同进步CSS的魅力就是让我们前端工程师像设计师一样进行网页的设计,我们能轻而易举的改变颜色、布局、制作出漂亮的影音效果等等,我们只需要改几行代码,不需...
国产开源API网关项目进入Apache孵化器:APISIX
点击蓝色“程序猿DD”关注我回复“资源”获取独家整理的学习资料!近日,又有一个开源项目加入了这个Java开源界大名鼎鼎的Apache基金会,开始进行孵化器。项目名称:AP...
程序员接私活怎样防止做完了不给钱?
首先跟大家说明一点,我们做 IT 类的外包开发,是非标品开发,所以很有可能在开发过程中会有这样那样的需求修改,而这种需求修改很容易造成扯皮,进而影响到费用支付,甚至出现做完了项目收不到钱的情况。 那么,怎么保证自己的薪酬安全呢? 我们在开工前,一定要做好一些证据方面的准备(也就是“讨薪”的理论依据),这其中最重要的就是需求文档和验收标准。一定要让需求方提供这两个文档资料作为开发的基础。之后开发
网页实现一个简单的音乐播放器(大佬别看。(⊙﹏⊙))
今天闲着无事,就想写点东西。然后听了下歌,就打算写个播放器。 于是乎用h5 audio的加上js简单的播放器完工了。 欢迎 改进 留言。 演示地点跳到演示地点 html代码如下`&lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;title&gt;music&lt;/title&gt; &lt;meta charset="utf-8"&gt
Python十大装B语法
Python 是一种代表简单思想的语言,其语法相对简单,很容易上手。不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了。本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并附上详细的实例代码。如能在实战中融会贯通、灵活使用,必将使代码更为精炼、高效,同时也会极大提升代码B格,使之看上去更老练,读起来更优雅。 1. for - else 什么?不是 if 和 else 才
数据库优化 - SQL优化
前面一篇文章从实例的角度进行数据库优化,通过配置一些参数让数据库性能达到最优。但是一些“不好”的SQL也会导致数据库查询变慢,影响业务流程。本文从SQL角度进行数据库优化,提升SQL运行效率。 判断问题SQL 判断SQL是否有问题时可以通过两个表象进行判断: 系统级别表象 CPU消耗严重 IO等待严重 页面响应时间过长
2019年11月中国大陆编程语言排行榜
2019年11月2日,我统计了某招聘网站,获得有效程序员招聘数据9万条。针对招聘信息,提取编程语言关键字,并统计如下: 编程语言比例 rank pl_ percentage 1 java 33.62% 2 c/c++ 16.42% 3 c_sharp 12.82% 4 javascript 12.31% 5 python 7.93% 6 go 7.25% 7
通俗易懂地给女朋友讲:线程池的内部原理
餐厅的约会 餐盘在灯光的照耀下格外晶莹洁白,女朋友拿起红酒杯轻轻地抿了一小口,对我说:“经常听你说线程池,到底线程池到底是个什么原理?”我楞了一下,心里想女朋友今天是怎么了,怎么突然问出这么专业的问题,但做为一个专业人士在女朋友面前也不能露怯啊,想了一下便说:“我先给你讲讲我前同事老王的故事吧!” 大龄程序员老王 老王是一个已经北漂十多年的程序员,岁数大了,加班加不动了,升迁也无望,于是拿着手里
经典算法(5)杨辉三角
杨辉三角 是经典算法,这篇博客对它的算法思想进行了讲解,并有完整的代码实现。
编写Spring MVC控制器的14个技巧
本期目录 1.使用@Controller构造型 2.实现控制器接口 3.扩展AbstractController类 4.为处理程序方法指定URL映射 5.为处理程序方法指定HTTP请求方法 6.将请求参数映射到处理程序方法 7.返回模型和视图 8.将对象放入模型 9.处理程序方法中的重定向 10.处理表格提交和表格验证 11.处理文件上传 12.在控制器中自动装配业务类 ...
腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹?
昨天,有网友私信我,说去阿里面试,彻底的被打击到了。问了为什么网上大量使用ThreadLocal的源码都会加上private static?他被难住了,因为他从来都没有考虑过这个问题。无独有偶,今天笔者又发现有网友吐槽了一道腾讯的面试题,我们一起来看看。 腾讯算法面试题:64匹马8个跑道需要多少轮才能选出最快的四匹? 在互联网职场论坛,一名程序员发帖求助到。二面腾讯,其中一个算法题:64匹
面试官:你连RESTful都不知道我怎么敢要你?
面试官:了解RESTful吗? 我:听说过。 面试官:那什么是RESTful? 我:就是用起来很规范,挺好的 面试官:是RESTful挺好的,还是自我感觉挺好的 我:都挺好的。 面试官:… 把门关上。 我:… 要干嘛?先关上再说。 面试官:我说出去把门关上。 我:what ?,夺门而去 文章目录01 前言02 RESTful的来源03 RESTful6大原则1. C-S架构2. 无状态3.统一的接
求小姐姐抠图竟遭白眼?痛定思痛,我决定用 Python 自力更生!
点击蓝色“Python空间”关注我丫加个“星标”,每天一起快乐的学习大家好,我是 Rocky0429,一个刚恰完午饭,正在用刷网页浪费生命的蒟蒻...一堆堆无聊八卦信息的网页内容慢慢使我的双眼模糊,一个哈欠打出了三斤老泪,就在此时我看到了一张图片:是谁!是谁把我女朋友的照片放出来的!awsl!太好看了叭...等等,那个背景上的一堆鬼画符是什么鬼?!真是看不下去!叔叔婶婶能忍,隔壁老王的三姨妈的四表...
为啥国人偏爱Mybatis,而老外喜欢Hibernate/JPA呢?
关于SQL和ORM的争论,永远都不会终止,我也一直在思考这个问题。昨天又跟群里的小伙伴进行了一番讨论,感触还是有一些,于是就有了今天这篇文。 声明:本文不会下关于Mybatis和JPA两个持久层框架哪个更好这样的结论。只是摆事实,讲道理,所以,请各位看官勿喷。 一、事件起因 关于Mybatis和JPA孰优孰劣的问题,争论已经很多年了。一直也没有结论,毕竟每个人的喜好和习惯是大不相同的。我也看
SQL-小白最佳入门sql查询一
不要偷偷的查询我的个人资料,即使你再喜欢我,也不要这样,真的不好;
项目中的if else太多了,该怎么重构?
介绍 最近跟着公司的大佬开发了一款IM系统,类似QQ和微信哈,就是聊天软件。我们有一部分业务逻辑是这样的 if (msgType = "文本") { // dosomething } else if(msgType = "图片") { // doshomething } else if(msgType = "视频") { // doshomething } else { // doshom...
致 Python 初学者
欢迎来到“Python进阶”专栏!来到这里的每一位同学,应该大致上学习了很多 Python 的基础知识,正在努力成长的过程中。在此期间,一定遇到了很多的困惑,对未来的学习方向感到迷茫。我非常理解你们所面临的处境。我从2007年开始接触 python 这门编程语言,从2009年开始单一使用 python 应对所有的开发工作,直至今天。回顾自己的学习过程,也曾经遇到过无数的困难,也曾经迷茫过、困惑过。开办这个专栏,正是为了帮助像我当年一样困惑的 Python 初学者走出困境、快速成长。希望我的经验能真正帮到你
“狗屁不通文章生成器”登顶GitHub热榜,分分钟写出万字形式主义大作
一、垃圾文字生成器介绍 最近在浏览GitHub的时候,发现了这样一个骨骼清奇的雷人项目,而且热度还特别高。 项目中文名:狗屁不通文章生成器 项目英文名:BullshitGenerator 根据作者的介绍,他是偶尔需要一些中文文字用于GUI开发时测试文本渲染,因此开发了这个废话生成器。但由于生成的废话实在是太过富于哲理,所以最近已经被小伙伴们给玩坏了。 他的文风可能是这样的: 你发现,...
程序员:我终于知道post和get的区别
是一个老生常谈的话题,然而随着不断的学习,对于以前的认识有很多误区,所以还是需要不断地总结的,学而时习之,不亦说乎
《程序人生》系列-这个程序员只用了20行代码就拿了冠军
你知道的越多,你不知道的越多 点赞再看,养成习惯GitHub上已经开源https://github.com/JavaFamily,有一线大厂面试点脑图,欢迎Star和完善 前言 这一期不算《吊打面试官》系列的,所有没前言我直接开始。 絮叨 本来应该是没有这期的,看过我上期的小伙伴应该是知道的嘛,双十一比较忙嘛,要值班又要去帮忙拍摄年会的视频素材,还得搞个程序员一天的Vlog,还要写BU...
相关热词 c# 图片上传 c# gdi 占用内存 c#中遍历字典 c#控制台模拟dos c# 斜率 最小二乘法 c#进程延迟 c# mysql完整项目 c# grid 总行数 c# web浏览器插件 c# xml 生成xsd
立即提问