首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

关于c#的socket,客户端发消息,服务端只接收一次的有关问题

2014-01-15 
关于c#的socket,客户端发消息,服务端只接收一次的问题.本帖最后由 wenyu_825 于 2014-01-14 14:59:57 编辑

关于c#的socket,客户端发消息,服务端只接收一次的问题.
本帖最后由 wenyu_825 于 2014-01-14 14:59:57 编辑


//服务端代码
using ServerDemo.roc.socket_package;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ServerDemo.windows_package
{
    public partial class WindowMain : Form
    {
        private Socket socket = null;
        public WindowMain()
        {
            InitializeComponent();
        }

        private void buttonOpen_Click(object sender, EventArgs e)
        {
            Thread threadListen = new Thread(new ThreadStart(listen));
            threadListen.IsBackground = true;
            threadListen.Start();
            
        }
        private void listen()
        {
            Console.WriteLine("Start Listening ...");
            appendtextBoxLog("Start Listening ...");
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //基于TCP/IP的网络上通讯;
            //Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); //基于UDP的网络上通讯;
            serverSocket.Bind(new IPEndPoint(IPAddress.Any, 6666));//设定该套接字的绑定IP,接受从任意IP地址发往端口6666的消息;//如果需要限制IP,就把IPAddress.Any改一下;
            serverSocket.Listen(1000);//将套接字设置为监听状态,并设置监听队列为100;//解释:如果1秒内有N多人并发访问可能暂时要存在队列里,估计1秒内几千人访问,设置100就足够用了.
            while (true)//死循环,即不发生异常中断的情况下一直接受消息 
            {
                this.socket = serverSocket.Accept();//(4)Create a new Socket for a newly created connection  
                appendtextBoxLog(this.socket.RemoteEndPoint.ToString()+" 连接成功");
                Thread thread = new Thread(new ThreadStart(start));
                thread.IsBackground = true;
                thread.Start();
            }
        }
        private void start()
        {
            SocketThreadClass stc = new SocketThreadClass(this.socket,this.textBoxLog);
        }

        private void button1_Click(object sender, EventArgs e)
        {

        }
        #region 窗体代码
        private void appendtextBoxLog(string msg)
        {
            textBoxLog.Invoke((MethodInvoker)delegate
            {
                textBoxLog.AppendText(msg+"\r\n");
            });
        }
        #endregion
    }
}
//接收消息的类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;

namespace ServerDemo.roc.socket_package
{
    class SocketThreadClass


    {
        private Socket socket = null;
        private TextBox textBoxLog = null;
        public SocketThreadClass(Socket socket,TextBox textBoxLog)
        {
            this.socket = socket;
            this.textBoxLog = textBoxLog;
            start();
            
        }
        private void start()
        {
            try
            {
                while (true)
                {
                    appendtextBoxLog("接收消息中...");
                    byte[] receiveBytes = new byte[1024];
                    socket.Receive(receiveBytes);//(4)获取服务器的响应数据;//远程主机强迫关了了一个现有连接异常,会触发
                    Console.WriteLine(Encoding.ASCII.GetString(receiveBytes));
                    appendtextBoxLog(Encoding.ASCII.GetString(receiveBytes));
                    appendtextBoxLog("接受完毕");
                }
            }
            catch (SocketException)//一般是远程主机强制关闭连接引发的异常.(例如:远程主机强制关闭了,我还在接收数据就引发了;如果远程主机正常关闭,即使我还在接收数据也不会引发异常.)
            {
                appendtextBoxLog(this.socket.RemoteEndPoint.ToString()+" 远程主机强制关闭连接");
                if (socket != null)
                {
                    socket.Shutdown(SocketShutdown.Both);
                    socket.Close();
                }
            }
        }
        #region 窗体代码
        private void appendtextBoxLog(string msg)
        {
            textBoxLog.Invoke((MethodInvoker)delegate
            {
                this.textBoxLog.AppendText(msg + "\r\n");
            });
        }
        #endregion
    }
}
//客户端代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace ClientDemo.windows_package
{
    public partial class WindowMain : Form
    {
        private Socket clientSocket = null;
        public WindowMain()
        {
            InitializeComponent();
        }

        private void buttonConnection_Click(object sender, EventArgs e)
        {
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);//(1)首先在服务器端定义一个套接字(socket),使用Tcp协议  
            //IPHostEntry ipHost = Dns.GetHostEntry("threadroc.xicp.net");//可以是域名也可以是IP地址;//还是说只能是域名?


            //IPAddress ipAddress = ipHost.AddressList[0];
            IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); 
            IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 6666);
            try
            {
                clientSocket.Connect(ipEndPoint);//(2)其次设定该套接字的链接IP,发送到指定IP地址的6666端
            }
            catch(SocketException)
            {
                Console.WriteLine("连接失败");
            }
            
            //byte[] receiveBytes = new byte[1024];
            //Console.WriteLine("----------------");
            //clientSocket.Receive(receiveBytes);//(4)获取服务器的响应数据  
            //Console.WriteLine("----------------");
            //Console.WriteLine("received from server: " + Encoding.ASCII.GetString(receiveBytes));
        }

        private void buttonSend_Click(object sender, EventArgs e)
        {
            string str = "hello, the socket test1";
            byte[] sendBytes = Encoding.ASCII.GetBytes(str);
            clientSocket.Send(sendBytes);//(3)发送数据比特流 
        }

        private void buttonClose_Click(object sender, EventArgs e)
        {
            clientSocket.Shutdown(SocketShutdown.Both);//(5)Disables sends and receives on a System.Net.Sockets.Socket  
            clientSocket.Close();//(6)关闭socket Connection,释放所有已占用资源  
        }
    }
}




以上就是全部代码了

但是我遇到的问题是,服务器只要点击开启按钮后,然后客户端连接,点击发送按钮发消息
服务器会收到;再然后客户端不管怎么点击发送按钮向服务器发送消息,服务器都收不到消息了.
即使客户端关闭程序,断开连接,重新连接上,点击发送按你,服务器还是收不到消息
这问题困扰我7个小时54分钟32.34秒了,希望大神灭了这孽障.
小弟在此不胜感激.
将来我若成为亿万富翁,必有后报.
[解决办法]
是否有异常,日志信息是否有显示“远程主机强制关闭连接”。其实你可以对服务端进行断点调试的,即使是多线程,断点也可以命中,但你要确保一点,同一个时间只有一个线程在工作,否则断点会乱跑。
[解决办法]
http://www.cnblogs.com/chenxizhang/archive/2011/09/10/2172994.html


你可以看下这个 写的不错.有例子 
[解决办法]
你这都是些什么呀,
while (true)//死循环,即不发生异常中断的情况下一直接受消息 
            {
                this.socket = serverSocket.Accept();//(4)Create a new Socket for a newly created connection  
                appendtextBoxLog(this.socket.RemoteEndPoint.ToString()+" 连接成功");
                Thread thread = new Thread(new ThreadStart(start));
                thread.IsBackground = true;
                thread.Start();
            }

------解决方案--------------------


你这里肯定是有问题的 socket服务端的套接字至少有两个  一个是监听是否有客户端连接用的  当有客户端连接的时候  调用开始监听套接字的Accpet方法会返回一个专门负责和客户端通信的套接字  而这个套接字才是负责通信的  而不是用监听套接字和客户端通信。
[解决办法]
http://bbs.csdn.net/topics/390513919?page=1#post-394999829
是不是你的原因
[解决办法]
http://bbs.csdn.net/topics/390597369
看下里面的那个例子
[解决办法]
别的乱七八糟的都不值得讨论了,仅说最成问题的:

每一次执行 serverSocket.Accept() 都返回了一个新的 socket 对象实例,你怎么能把之前的 this.socket 变量所引用的丢掉、让它引用新的对象呢?如果这样,别的地方使用 this.socket 变量一定会张冠李戴。

热点排行