2 qq 30109881 qq_30109881 于 2016.05.11 21:56 提问

为什么我的程序老是未响应,而且与客户端交流的时候也会强迫断开?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace skt_sv
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
TextBox.CheckForIllegalCrossThreadCalls = false;//关闭跨线程控件修改程序检查
}

    ///监听套接字
    private static Socket listener = null;

    //存储接收信息
   // private byte[] recvBytes = new byte[1024];


    //存储键值信息
    private List<string> listname=new List<string>();

    /// <summary>
    /// 监听端口
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            //配置信息
            int port = 5555;
            string host = "127.0.0.1";
            IPAddress ip = IPAddress.Parse(host);
            IPEndPoint ipe = new IPEndPoint(ip, port);
            listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            listener.Bind(ipe);
            MessageBox.Show("启动成功!!");
            //当监听到连接请求的时候再创建线程
            listener.Listen(100);
            while (true)
            {
                Socket sktmsg = listener.Accept();
                Thread threadWatch = new Thread(_sktThread);
                threadWatch.IsBackground = true;
                threadWatch.Start(sktmsg);
            }
        }
        catch(Exception error)
        {
            MessageBox.Show(error.ToString());
        }
    }

    Dictionary<string, Socket> dicConn = new Dictionary<string, Socket>();  //字典存储信息

    /// <summary>
    /// 被线程调用 监听连接端口
    /// </summary>
    /// <param name="data"></param>
    private void _sktThread(object data)
    {
        while (true)
        {
            Socket sktmsg = data as Socket;
            string recvstr;
            byte[] recvBytes = new byte[1024];
            sktmsg.Receive(recvBytes);
            recvstr = Encoding.UTF8.GetString(recvBytes);  //接收到的消息
            //MessageBox.Show(recvstr);
            if (recvstr[0] == '*') //首次连接存储相应客户端信息,并且将用户信息发送给已经连接的客户端
            {
                firstLink(recvstr, sktmsg);
            }
            else if (recvstr[0] == '#') //发送聊天内容
            {
                sktsend(recvstr);
            }
        }
    }

    /// <summary>
    /// 处理初次连接的问题
    /// </summary>
    /// <param name="recvstr"></param>
    private void firstLink(string recvstr,Socket sktmsg)
    {
        byte[] sendBytes = new byte[1024];
        string sendstr = "*";
        string strbegin = "*";
        string strend = "#";
        int indexA = recvstr.IndexOf(strbegin);
        int indexB = recvstr.IndexOf(strend);
        string name = recvstr.Substring(indexA+1,indexB-indexA-1);
        dicConn.Add(name,sktmsg);
        for (int i=0;i<listname.Count;i++)
        {
            sendstr += listname[i] + "*";
        }
        listname.Add(name);
        sendBytes = Encoding.UTF8.GetBytes(sendstr);
        sktmsg.Send(sendBytes);//给初次连接的客户端发送目前已经在线的用户
        Socket send = null;
        for (int i = 0; i < listname.Count - 1; i++ ) //给已经在线的用户发送新连接的客户端的信息
        {
            byte[] sendname = new byte[1024];
            send = dicConn[listname[i]];
            sendname = Encoding.UTF8.GetBytes("*"+name+"*");
            send.Send(sendname);
        }
    }

    /// <summary>
    /// 处理聊天问题
    /// </summary>
    /// <param name="recvstr"></param>
    private void sktsend(string recvstr) 
    {
        byte[] sendBytes = new byte[1024];
        Socket sendskt;
        string strbegin = "%";
        string strend = "&";
        int indexA = recvstr.IndexOf(strbegin);
        int indexB = recvstr.IndexOf(strend);
        string name = recvstr.Substring(indexA+1,indexB-indexA-1);
        sendskt = dicConn[name];
        sendBytes = Encoding.UTF8.GetBytes(recvstr);
        sendskt.Send(sendBytes,sendBytes.Length,0);
        sendskt.Close();
    }


    /// <summary>
    /// 程序终止
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void button2_Click(object sender, EventArgs e)
    {
        MessageBox.Show("程序终止!");
        Application.Exit();
    }
}

}

1个回答

yege2006
yege2006   2016.05.12 09:30

网络访问一般建议在子线程中进行,因为网络访问会占用很长时间,可能会导致线程阻塞从而出现未响应的状况

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!