为了学习Socket,从网上down了一下实例,进行调试学习,程序很简单,就是服务端和客户端进行对话聊天,但是发现在连续发送内容时,有的信息收不到,没有反应。这是怎么回事,是不是传说的丢包问题,怎样才能解决,实现稳定的对话。
不是都收不到,现在是不稳定,快速输入,点发送,有的能收到,有的就收不到。
谢谢

解决方案 »

  1.   

    服务端代码:
    namespace ServerSocketForms
    {
        public partial class ServerSocketTestForm : Form
        {
            #region 变量列表
            /// <summary>
            /// 服务端SOCKET对象
            /// </summary>
            private Socket ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);        /// <summary>
            /// 客户端SOCKET
            /// </summary>
            private Socket ClientSocket = null;        /// <summary>
            /// 客户端终结点
            /// </summary>
            private IPEndPoint ClientEndPoint = null;        /// <summary>
            /// 服务端终结点
            /// </summary>
            private IPEndPoint ServerEndPoint = null;        /// <summary>
            /// 客户端终结点端口
            /// </summary>
            private const int CLIENT_END_POINT_PORT = 5566;        /// <summary>
            /// 服务器端终结点端口
            /// </summary>
            private const int SERVER_END_POINT_PORT = 5533;
            #endregion        #region 构造函数
            public ServerSocketTestForm()
            {
                InitializeComponent();
            }
            #endregion        #region 事件列表        /// <summary>
            /// 窗体加载事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Form1_Load(object sender, EventArgs e)
            {
                Control.CheckForIllegalCrossThreadCalls = false;            ThreadServerListen();            txtContent.Focus();
            }        /// <summary>
            /// 向客户端发送数据
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnClientSend_Click(object sender, EventArgs e)
            {
                ThreadClientrSendData();
            }        /// <summary>
            /// 关闭程序
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnExit_Click(object sender, EventArgs e)
            {
                Environment.Exit(0);
            }
            #endregion        #region 函数列表
            #region Server
            /// <summary>
            /// 开始监听
            /// </summary>
            private void StartServerListenAndReceiveData()
            {
                try
                {
                    //如果没有绑定则执行绑定当地终结点操作
                    if (!ServerSocket.IsBound)
                    {
                        //设置终结点
                        SetEndPoint();                    //绑定本地结点
                        ServerSocket.Bind(ServerEndPoint);                    //开启监听
                        ServerSocket.Listen(20);                    listBox1.Items.Add(string.Format("成功开启监听({0}:{1})[{2}]", ServerEndPoint.Address, ServerEndPoint.Port, DateTime.Now.ToString()));                    ClientSocket = ServerSocket.Accept();
                    }                //接收数据开始
                    ServerReceiveData();
                }
                catch
                {
                    MessageBox.Show(string.Format("开启监听{0}:{1}失败!请检查服务端IP地址是否配置正确。", ServerEndPoint.Address, ServerEndPoint.Port), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }        /// <summary>
            /// 线程监听操作
            /// </summary>
            private void ThreadServerListen()
            {
                //接收数据线程
                Thread ReceiveThread = new Thread(new ThreadStart(StartServerListenAndReceiveData));            //后台运行
                ReceiveThread.IsBackground = true;            //开启线程
                ReceiveThread.Start();
            }        /// <summary>
            /// 接收数据
            /// </summary>
            private void ServerReceiveData()
            {
                try
                {
                    while (true)
                    {
                        Thread.Sleep(1);
                        byte[] bytes = new byte[ClientSocket.Available];                    //接收数据
                        int butter = ClientSocket.Receive(bytes);                    if (butter > 0)
                        {
                            string strData = string.Format("{0}", Encoding.UTF8.GetString(bytes));
                            listBox1.Items.Add(string.Format("[{0}][{1}]", ((IPEndPoint)ClientSocket.RemoteEndPoint).Address, DateTime.Now.ToString()));
                            listBox1.Items.Add(string.Format("  {0}", strData));
                            listBox1.SelectedIndex = listBox1.Items.Count - 1;
                        }                    //客户端SOCKET
                        ClientSocket = ServerSocket.Accept();
                    }
                }
                catch (Exception err)
                {
                    MessageBox.Show(err.ToString());
                }
            }
            #endregion        #region Client        /// <summary>
            /// 线程发送数据
            /// </summary>
            private void ThreadClientrSendData()
            {
                Thread thread = new Thread(new ThreadStart(ClientSendData));
                thread.IsBackground = true;
                thread.Priority = ThreadPriority.Highest;
                thread.Start();
            }        /// <summary>
            /// 发送数据
            /// </summary>
            private void ClientSendData()
            {
                if (string.IsNullOrEmpty(txtContent.Text.Trim()))
                {
                    MessageBox.Show("请填写消息内容。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    txtContent.Focus();
                    return;
                }
                try
                {
                    if (ClientSocket == null)
                    {
                        MessageBox.Show("没有可用的连接。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        return;
                    }                btnClientSend.Enabled = false;
                    btnClientSend.Text = "发送中...";
                    byte[] bytes = null;                bytes = Encoding.UTF8.GetBytes(txtContent.Text.Trim());                //重新调整客户端端口号
                    ClientEndPoint = (IPEndPoint)ClientSocket.RemoteEndPoint;
                    ClientEndPoint = new IPEndPoint(ClientEndPoint.Address, CLIENT_END_POINT_PORT);                Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                socket.Connect(ClientEndPoint);                //向客户端发送数据
                    socket.Send(bytes);
                    socket.Close();                listBox1.Items.Add(string.Format("[{0}][{1}]", ((IPEndPoint)ServerSocket.LocalEndPoint).Address, DateTime.Now.ToString()));                listBox1.Items.Add(string.Format("  {0}", txtContent.Text.Trim()));
                    listBox1.SelectedIndex = listBox1.Items.Count - 1;                btnClientSend.Enabled = true;
                    btnClientSend.Text = "发送";                txtContent.Text = "";
                    txtContent.Focus();
                }
                catch
                {
                    MessageBox.Show(string.Format("服务器{0}:{1}连接失败!请检查目标机器端口号{1}是否被占用。", ClientEndPoint.Address, ClientEndPoint.Port), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            #endregion        /// <summary>
            /// 设置服务器端终结点
            /// </summary>
            private void SetEndPoint()
            {
                IPHostEntry hostEntry = Dns.GetHostByName(Dns.GetHostName());            IPAddress address = hostEntry.AddressList[0];//5_1_a_s_p_x            ServerEndPoint = new IPEndPoint(address, SERVER_END_POINT_PORT);
            }
            #endregion
        }
    }
      

  2.   

    客户端代码:namespace ClientSocketForms
    {
        public partial class ClientSocketTestForm : Form
        {
                   /// 客户端终结点端口
                   private const int CLIENT_END_POINT_PORT = 5566;        /// <summary>
            /// 服务器端终结点端口
            /// </summary>
            private const int SERVER_END_POINT_PORT = 5533;        /// <summary>
            /// ****************此处要改成服务器的IP,否则程序将运行不起来****************
            /// </summary>
            private static string SERVER_IP
            {
                get
                {
                    return global::ClientSocketForms.Properties.Settings.Default.ServerIP;
                }
            }        /// <summary>
            /// 服务器结点
            /// </summary>
            private IPEndPoint ServerEndPoint = null;        /// <summary>
            /// 客户端SOCKET
            /// </summary>
            private Socket ClientSocket = null;        /// <summary>
            /// 服务端SOCKET
            /// </summary>
            private Socket ServerSocket = null;        /// <summary>
            /// 客户端监听SOCKET
            /// </summary>
            private Socket ClientListenSocket = null;
            #endregion        #region 构造函数
            public ClientSocketTestForm()
            {
                InitializeComponent();
            }
            #endregion        #region 事件列表
            /// <summary>
            /// 发送消息事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void button1_Click(object sender, EventArgs e)
            {
                ThreadSendData();
            }        /// <summary>
            /// 关闭程序
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnExit_Click(object sender, EventArgs e)
            {
                Application.Exit();
            }        /// <summary>
            /// 页面加载事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void Form1_Load(object sender, EventArgs e)
            {
                Control.CheckForIllegalCrossThreadCalls = false;            //接收服务器端数据
                ThreadReceiveData();
            }        /// <summary>
            /// 清空列表框
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnClear_Click(object sender, EventArgs e)
            {
                listBox1.Items.Clear();
            }       /// 打开服务器IP配置窗口
            private void 服务器IP设置ToolStripMenuItem_Click(object sender, EventArgs e)
            {
                ServerIPForm ServerIp = new ServerIPForm();
                ServerIp.ShowDialog();
            }
            #endregion        #region 方法列表
            /// <summary>
            /// 向服务器发送数据
            /// </summary>
            private void SendData()
            {
                IPAddress ServerIPAdd = null;            if (!IPAddress.TryParse(SERVER_IP, out ServerIPAdd))
                {
                    MessageBox.Show("服务器端IP地址配置不正确!请重新配置服务器端IP地址。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);                //显示服务器IP配置界面
                    ServerIPForm frmIp = new ServerIPForm();
                    frmIp.ShowDialog();
                    return;
                }            ServerEndPoint = new IPEndPoint(ServerIPAdd, SERVER_END_POINT_PORT);
                if (string.IsNullOrEmpty(txtContent.Text.Trim()))
                {
                    MessageBox.Show("请填写消息内容。", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    txtContent.Focus();
                    return;
                }            try
                {
                    button1.Enabled = false;
                    button1.Text = "发送中...";                //客户端SOCKET
                    ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);                //建立与服务器端的连接
                    ClientSocket.Connect(ServerEndPoint);                byte[] bytes = new byte[1024];                bytes = Encoding.UTF8.GetBytes(txtContent.Text.Trim());                ClientSocket.Send(bytes);
                    ClientSocket.Shutdown(SocketShutdown.Both);
                    listBox1.Items.Add(string.Format("[{0}][{1}]", ((IPEndPoint)ClientSocket.LocalEndPoint).Address, DateTime.Now.ToString()));                listBox1.Items.Add(string.Format("  {0}", txtContent.Text.Trim()));
                    ClientSocket.Close();
                    listBox1.SelectedIndex = listBox1.Items.Count - 1;                txtContent.Text = "";
                    txtContent.Focus();                button1.Enabled = true;
                    button1.Text = "发送";
                }
                catch (Exception err)
                {
                    MessageBox.Show(string.Format("服务器{0}:{1}连接失败!请检查目标机器IP是否正确。", ServerEndPoint.Address, ServerEndPoint.Port), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);                button1.Enabled = true;
                    button1.Text = "发送";                //显示服务器IP配置界面
                    ServerIPForm frmIp = new ServerIPForm();
                    frmIp.ShowDialog();
                    return;
                }
            }        /// <summary>
            /// 线程发送数据
            /// </summary>
            private void ThreadSendData()
            {
                Thread thread = new Thread(new ThreadStart(SendData));
                thread.IsBackground = true;
                thread.Priority = ThreadPriority.Highest;
                thread.Start();
            }        /// <summary>
            /// 开始监听
            /// </summary>
            private void StartClientListenAndReceiveData()
            {
                //客户端侦听SOCKET
                ClientListenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);            IPHostEntry hostEntry = Dns.GetHostByName(Dns.GetHostName());            IPAddress address = hostEntry.AddressList[0];            try
                {
                    //绑定本地结点并开启本地监听
                    if (!ClientListenSocket.IsBound)
                    {
                        ClientListenSocket.Bind(new IPEndPoint(address, CLIENT_END_POINT_PORT));
                        ClientListenSocket.Listen(20);
                    }                listBox1.Items.Add(string.Format("成功开启监听({0}:{1})[{2}]。", address, CLIENT_END_POINT_PORT, DateTime.Now.ToString()));                //接收数据
                    ServerReceiveData();
                }
                catch
                {
                    MessageBox.Show(string.Format("服务器{0}:{1}连接失败!请检查目标机器端口号{1}是否被占用。", address, CLIENT_END_POINT_PORT), "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }        /// <summary>
            /// 接收服务端数据
            /// </summary>
            private void ServerReceiveData()
            {
                try
                {
                    while (true)
                    {
                        Thread.Sleep(1);
                        //服务端SOCKET
                        ServerSocket = ClientListenSocket.Accept();
                        byte[] bytes = new byte[ServerSocket.Available];
                        //接收数据
                        int butter = ServerSocket.Receive(bytes);
                        if (butter > 0)
                        {
                            string strData = string.Format("{0}", Encoding.UTF8.GetString(bytes));
                            listBox1.Items.Add(string.Format("[{0}][{1}]", ((IPEndPoint)ServerSocket.RemoteEndPoint).Address, DateTime.Now.ToString()));
                            listBox1.Items.Add(string.Format("  {0}", strData));
                            listBox1.SelectedIndex = listBox1.Items.Count - 1;
                        }
                    }
                }
                catch (Exception err)
                {
                    MessageBox.Show(err.ToString());
                }
            }
            /// <summary>
            /// 线程接收数据
            /// </summary>
            private void ThreadReceiveData()
            {
                Thread thread = new Thread(new ThreadStart(StartClientListenAndReceiveData));
                thread.IsBackground = true;
                thread.Start();
            }
            #endregion
        }
    }
      

  3.   

    tcp应该不会丢包的,如果丢包,应该是网络的问题,
      

  4.   

    这种代码.........到处都是惨不忍睹的。随便找一个吧,string strData = string.Format("{0}", Encoding.UTF8.GetString(bytes));
    这里bytes中只有前buffer个字节是你接收到内容,怎么能把整个bytes作为接收到的内容呢?
      

  5.   

    再比如说吧,你的所谓“服务器端”仅仅在Form初始化时ServerSocket.Listen(20);
    ClientSocket = ServerSocket.Accept();
    ServerReceiveData();
    而你的所谓“客户端”则是每当btnClientSend_Click时弄个所谓线程去单独调用ClientSendData,这能够让你服务器获得第二个会话?晕啊。我不知道你从哪里抄来的代码。我建议你把这些代码简化到20行以内(只要了解必要的几行代码就够了),或者干脆删除(另外找人学习)。另外请告诉我你是从哪里抄来的代码?这其实很重要。我们可以知道这是哪一个坑人的培训学校的教学。