用Socket 做的一个聊天小程序,为什么总是丢包,如何解决

lid123456 2013-02-16 08:25:28
为了学习Socket,从网上down了一下实例,进行调试学习,程序很简单,就是服务端和客户端进行对话聊天,但是发现在连续发送内容时,有的信息收不到,没有反应。这是怎么回事,是不是传说的丢包问题,怎样才能解决,实现稳定的对话。
不是都收不到,现在是不稳定,快速输入,点发送,有的能收到,有的就收不到。
谢谢
...全文
239 6 点赞 打赏 收藏 举报
写回复
6 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
stonespace 2013-02-17
tcp应该不会丢包的,如果丢包,应该是网络的问题,
  • 打赏
  • 举报
回复
再比如说吧,你的所谓“服务器端”仅仅在Form初始化时
ServerSocket.Listen(20);
ClientSocket = ServerSocket.Accept();
ServerReceiveData();
而你的所谓“客户端”则是每当btnClientSend_Click时弄个所谓线程去单独调用ClientSendData,这能够让你服务器获得第二个会话?晕啊。 我不知道你从哪里抄来的代码。我建议你把这些代码简化到20行以内(只要了解必要的几行代码就够了),或者干脆删除(另外找人学习)。 另外请告诉我你是从哪里抄来的代码?这其实很重要。我们可以知道这是哪一个坑人的培训学校的教学。
  • 打赏
  • 举报
回复
这种代码.........到处都是惨不忍睹的。 随便找一个吧,
string strData = string.Format("{0}", Encoding.UTF8.GetString(bytes));
这里bytes中只有前buffer个字节是你接收到内容,怎么能把整个bytes作为接收到的内容呢?
  • 打赏
  • 举报
回复
lid123456 2013-02-16
客户端代码: 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 } }
  • 打赏
  • 举报
回复
lid123456 2013-02-16
服务端代码: 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 } }
  • 打赏
  • 举报
回复
菜牛 2013-02-16
代码代码代码
  • 打赏
  • 举报
回复
相关推荐
发帖
C#
加入

10.6w+

社区成员

.NET技术 C#
申请成为版主
帖子事件
创建了帖子
2013-02-16 08:25
社区公告

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