• Socket进程阻塞AcceptSocket()卡死!救

  • 本文关于 c#
  • CodeGo.net > Socket进程阻塞AcceptSocket()卡死!救
  •  

    Socket进程阻塞AcceptSocket()卡死!救



    c#
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Net.Sockets;
    using System.Net;
    using System.Collections;
    using System.Threading;
    namespace HttpProxyDemo
    {
    public partial class MainForm : Form
    {
    public MainForm()
    {
    InitializeComponent();
    }
    private void MainForm_Load(object sender, EventArgs e)
    {
    }
    int ProxyPort;
    /// <summary>
    /// 启动Http代理服务器
    /// </summary>
    public void MainStart()
    {
    TcpListener tcplistener = null;
    try
    {
    // 开始监听端口
    tcplistener = new TcpListener(IPAddress.Parse("127.0.0.1"), ProxyPort);//Dns.GetHostAddresses(Dns.GetHostName())[0]
    tcplistener.Start();
    //Console.WriteLine("侦听端口号: " + ProxyPort.ToString());
    this.richTextBox1.AppendText("侦听端口号: " + ProxyPort.ToString());
    }
    catch (Exception e)
    {
    this.richTextBox1.AppendText("启动代理服务器失败: " + e.Message);
    }
    while (true)
    {
    try
    {
    // 接受客户端端连接
    Socket socket = tcplistener.AcceptSocket();
    //上面卡死*
    // 启动新线程,处理连接
    ClientSocket = socket;
    Thread thread = new Thread(new ThreadStart(Start));
    thread.Start();
    }
    catch (Exception e)
    {
    this.richTextBox1.AppendText("接受客户端端连接异常:" + e.Message);
    }
    }
    }
    // 客户端端socket
    Socket ClientSocket;
    // 设定编码
    Encoding Default = Encoding.GetEncoding("gb2312");
    public void Start()
    {
    // 客户端端缓冲区,读取客户端端命令
    Byte[] ReadBuff = new byte[1024 * 10];
    try
    {
    int Length = ClientSocket.Receive(ReadBuff);
    // 没有读到数据
    if (0 == Length)
    {
    this.richTextBox1.AppendText("从客户端端读取命令错误");
    ClientSocket.Shutdown(SocketShutdown.Both);
    ClientSocket.Close();
    return;
    }
    }
    // 读取出现异常
    catch (Exception e)
    {
    this.richTextBox1.AppendText("读取客户端端异常:" + e.Message);
    }
    // 来自客户端端的HTTP求字符串
    string ClientMsg = Default.GetString(ReadBuff);
    // 根据rnrn截取求行
    //string Line = ClientMsg.Substring(0, ClientMsg.IndexOf("rn"));
    //string[] CmdArray = Line.Split(' ');
    // GET http://www.test.com:80/index.php HTTP/1.1
    // CONNECT www.test.com:443 HTTP/1.1
    //string Cmd = CmdArray[0];
    //string RawUrl = CmdArray[1];
    string RawUrl = "http://86.108.17.138";
    this.richTextBox1.AppendText("原始求: "+ ClientMsg);
    // GET,POST和其他
    DoOther(RawUrl, ClientMsg);
    }
    /// <summary>
    /// 处理GET,POST等命令。使用POLL,在代理服务器中强制去掉Keep-Alive能力
    /// </summary>
    /// <param name="RawUrl"></param>
    /// <param name="ClientMsg"></param>
    public void DoOther(string RawUrl, string ClientMsg)
    {
    RawUrl = RawUrl.Substring(0 + "http://".Length);
    int Port;
    string Host;
    string Url;
    // 下面是割处理此处应该用正则匹配,不过我不擅长,因此手动切割 CodeGo.net,—_—!
    int index1 = RawUrl.IndexOf(':');
    // 没有端口
    if (index1 == -1)
    {
    Port = 80;
    int index2 = RawUrl.IndexOf('/');
    // 没有目录
    if (index2 == -1)
    {
    Host = RawUrl;
    Url = "/";
    }
    else
    {
    Host = RawUrl.Substring(0, index2);
    Url = RawUrl.Substring(index2);
    }
    }
    else
    {
    int index2 = RawUrl.IndexOf('/');
    // 没有目录
    if (index2 == -1)
    {
    Host = RawUrl.Substring(0, index1);
    Port = Int32.Parse(RawUrl.Substring(index1 + 1));
    Url = "/";
    }
    else
    {
    // /出现在:之前,则说明:后面的不是端口
    if (index2 < index1)
    {
    Host = RawUrl.Substring(0, index2);
    Port = 80;
    }
    else
    {
    Host = RawUrl.Substring(0, index1);
    Port = Int32.Parse(RawUrl.Substring(index1 + 1, index2 - index1 - 1));
    }
    Url = RawUrl.Substring(index2);
    }
    }
    Console.WriteLine("Host is:{0}, Port is:{1}, Url is:{2}", Host, Port, Url);
    IPAddress[] address = null;
    try
    {
    IPHostEntry IPHost = Dns.GetHostEntry(Host);
    address = IPHost.AddressList;
    this.richTextBox1.AppendText("Web服务器IP地址: " + address[0]);
    }
    catch (Exception e)
    {
    this.richTextBox1.AppendText("解析服务器地址异常: " + e.Message);
    }
    Socket IPsocket = null;
    try
    {
    // 连接到真实WEB服务器
    IPEndPoint ipEndpoint = new IPEndPoint(address[0], Port);
    IPsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    IPsocket.Connect(ipEndpoint);
    // 对WEB服务器端传送HTTP求命令,将原始HTTP求中HTTP PROXY部包装去掉
    string ReqData = ClientMsg;
    // 改写头中的URL,从http://www.test.com/index.php改为/index.php
    ReqData = ReqData.Replace("http://" + RawUrl, Url);
    // 按照rn切HTTP头
    string[] ReqArray = ReqData.Split(new string[1] { "rn" }, StringSplitOptions.None);
    ReqData = "";
    // 改写Keep-Alive等字段
    for (int index = 0; index < ReqArray.Length; index++)
    {
    if (ReqArray[index].StartsWith("Proxy-Connection:"))
    {
    ReqArray[index] = ReqArray[index].Replace("Proxy-Connection:", "Connection:");
    }
    // 修改后的字段combinations成求
    if (ReqArray[index] != "")
    {
    ReqData = ReqData + ReqArray[index] + "rn";
    }
    }
    ReqData = ReqData.Trim();
    byte[] SendBuff = Default.GetBytes(ReqData);
    IPsocket.Send(SendBuff);
    }
    catch (Exception e)
    {
    this.richTextBox1.AppendText("发送求到服务器异常: " + e.Message);
    }
    // 使用Poll来判断完成,某些站点会出问题
    while (true)
    {
    Byte[] RecvBuff = new byte[1024 * 20];
    try
    {
    if (!IPsocket.Poll(15 * 1000 * 1000, SelectMode.SelectRead))
    {
    this.richTextBox1.AppendText("HTTP超时,关闭连接");
    break;
    }
    }
    catch (Exception e)
    {
    Console.WriteLine("Poll: {0}" + e.Message);
    break;
    }
    int Length = 0;
    try
    {
    Length = IPsocket.Receive(RecvBuff);
    if (0 == Length)
    {
    this.richTextBox1.AppendText("服务端关闭");
    break;
    }
    //Console.WriteLine("从服务端收到字节:{0}", Length);
    this.richTextBox1.AppendText("从服务端收到字节:" + Length);
    // Console.WriteLine("内容:{0}", Encoding.Default.GetString(RecvBuff));
    }
    catch (Exception e)
    {
    this.richTextBox1.AppendText("Recv: " + e.Message);
    break;
    }
    try
    {
    Length = ClientSocket.Send(RecvBuff, Length, 0);
    // Console.WriteLine("发送字节到客户端端:{0}", Length);
    this.richTextBox1.AppendText("发送字节到客户端端:" + Length);
    }
    catch (Exception e)
    {
    //Console.WriteLine("Send: " + e.Message);
    this.richTextBox1.AppendText("Send: " + e.Message);
    }
    }
    try
    {
    ClientSocket.Shutdown(SocketShutdown.Both);
    ClientSocket.Close();
    IPsocket.Shutdown(SocketShutdown.Both);
    IPsocket.Close();
    }
    catch (Exception e)
    {
    //Console.WriteLine(e.Message);
    }
    }
    private void btn_set_Click(object sender, EventArgs e)
    {
    this.ProxyPort = int.Parse(this.clientPort.Text);
    MainStart();
    }
    }
    }

    本文地址 :CodeGo.net/1482662/
    -------------------------------------------------------------------------------------------------------------------------
    1.比如
    private void button1_Click(object sender, EventArgs e)
    {
    Thread threadStart;
    threadStart = new Thread(new ThreadStart(WaitingOpen));//
    threadStart.Priority = ThreadPriority.Highest;
    threadStart.Start();
    }
    private delegate void InvokeDelegate1();
    public void WaitingOpen()
    {
    if (this.InvokeRequired)
    this.BeginInvoke(new InvokeDelegate1(WaitingOpen_Fun));
    }
    private void WaitingOpen_Fun()
    {
    在这里就可以访问并操作界面控件,
    把你MainStart函数内容写在这里
    }
    2. private void btn_set_Click(object sender, EventArgs e)
    {
    this.ProxyPort = int.Parse(this.clientPort.Text);
    Thread thread = new Thread(new ThreadStart(Start111));
    thread.Start();
    }
    void Start111()
    {
    MainStart();
    }
    大概思路是这样写!
    还有tcplistener.AcceptSocket();这句就是要阻塞接收,没有消息会一直阻塞下去。所以你要开线程
    还有线程中如果要访问界面控件的话用委托
    3. MainStart函数要在线程里启动,即btn_set_Click事件里开线程启动MainStart()
    你想想,你的MainStart函数是个while(true)循环监听,不开线程当然会卡
    本文标题 :Socket进程阻塞AcceptSocket()卡死!救
    本文地址 :CodeGo.net/1482662/
    1. 无法读取的True Type字体文件在我的WPF应用程序!
    2. C# winform中的flowlayoutpanel
    3. 设置ComboBox.SelectedIndexrestOneWayToSourceconstraints力ComboBox.SelectedItem
    4. winform传参问题
    5. 如何修改在数据表中的数据在C#
    6. 程序打包时提示"配置文件app.config正用于配置所有的可执行文件"
    7. 如何使用。NET Compact Framework中播放视频?
    8. 有想不通,想来问下
    9. IHTMLTxtRange.pasteHTML不会取代旧的HTML
    10. 教一类型转换

     
    

    Copyright © 2017 CodeGo.net
    http://codego.net/xinwen/ 足球比分网 足球比分 医药招商网 邵阳县新闻