C#实现多线程的Web代理服务器实例

本文实例讲述了C#实现多线程的Web代理服务器。分享给大家供大家参考。具体如下:

/**
Proxy.cs:
C# Programming Tips & Techniques
by Charles Wright, Kris Jamsa
Publisher: Osborne/McGraw-Hill (December 28, 2001)
ISBN: 0072193794
*/
// Proxy.cs -- Implements a multi-threaded Web proxy server
//
//    Compile this program with the following command line:
//     C:>csc Proxy.cs
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.IO;
using System.Threading;
namespace nsProxyServer
{
 public class ProxyServer
 {
  static public void Main (string [] args)
  {
   int Port = 3125;
   if (args.Length > 0)
   {
    try
    {
     Port = Convert.ToInt32 (args[0]);
    }
    catch
    {
     Console.WriteLine ("Please enter a port number.");
     return;
    }
   }
   try
   {
    // Create a listener for the proxy port
    TcpListener sockServer = new TcpListener (Port);
    sockServer.Start ();
    while (true)
    {
     // Accept connections on the proxy port.
     Socket socket = sockServer.AcceptSocket ();
     // When AcceptSocket returns, it means there is a connection. Create
     // an instance of the proxy server class and start a thread running.
     clsProxyConnection proxy = new clsProxyConnection (socket);
     Thread thrd = new Thread (new ThreadStart (proxy.Run));
     thrd.Start ();
     // While the thread is running, the main program thread will loop around
     // and listen for the next connection request.
    }
   }
   catch (IOException e)
   {
    Console.WriteLine (e.Message);
   }
  }
 }
 class clsProxyConnection
 {
  public clsProxyConnection (Socket sockClient)
  {
   m_sockClient = sockClient;
  }
  Socket m_sockClient; //, m_sockServer;
  Byte [] readBuf = new Byte [1024];
  Byte [] buffer = null;
  Encoding ASCII = Encoding.ASCII;
  public void Run ()
  {
   string strFromClient = "";
   try
   {
    // Read the incoming text on the socket/
    int bytes = ReadMessage (m_sockClient,
           readBuf, ref strFromClient);
    // If it's empty, it's an error, so just return.
    // This will termiate the thread.
    if (bytes == 0)
     return;
    // Get the URL for the connection. The client browser sends a GET command
    // followed by a space, then the URL, then and identifer for the HTTP version.
    // Extract the URL as the string betweeen the spaces.
    int index1 = strFromClient.IndexOf (' ');
    int index2 = strFromClient.IndexOf (' ', index1 + 1);
    string strClientConnection =
      strFromClient.Substring (index1 + 1, index2 - index1);
    if ((index1 < 0) || (index2 < 0))
    {
     throw (new IOException ());
    }
    // Write a messsage that we are connecting.
    Console.WriteLine ("Connecting to Site " +
         strClientConnection);
    Console.WriteLine ("Connection from " +
         m_sockClient.RemoteEndPoint);
    // Create a WebRequest object.
    WebRequest req = (WebRequest) WebRequest.Create
              (strClientConnection);
    // Get the response from the Web site.
    WebResponse response = req.GetResponse ();
    int BytesRead = 0;
    Byte [] Buffer = new Byte[32];
    int BytesSent = 0;
    // Create a response stream object.
    Stream ResponseStream = response.GetResponseStream();
    // Read the response into a buffer.
    BytesRead = ResponseStream.Read(Buffer,0,32);
    StringBuilder strResponse = new StringBuilder("");
    while (BytesRead != 0)
    {
     // Pass the response back to the client
     strResponse.Append(Encoding.ASCII.GetString(Buffer,
          0, BytesRead));
     m_sockClient.Send(Buffer, BytesRead, 0);
     BytesSent += BytesRead;
     // Read the next part of the response
     BytesRead = ResponseStream.Read(Buffer, 0, 32);
    }
   }
   catch (FileNotFoundException e)
   {
    SendErrorPage (404, "File Not Found", e.Message);
   }
   catch (IOException e)
   {
    SendErrorPage (503, "Service not available", e.Message);
   }
   catch (Exception e)
   {
     SendErrorPage (404, "File Not Found", e.Message);
     Console.WriteLine (e.StackTrace);
     Console.WriteLine (e.Message);
   }
   finally
   {
    // Disconnect and close the socket.
    if (m_sockClient != null)
    {
     if (m_sockClient.Connected)
     {
      m_sockClient.Close ();
     }
    }
   }
   // Returning from this method will terminate the thread.
  }
  // Write an error response to the client.
  void SendErrorPage (int status, string strReason, string strText)
  {
   SendMessage (m_sockClient, "HTTP/1.0" + " " +
       status + " " + strReason + "\r\n");
   SendMessage (m_sockClient, "Content-Type: text/plain" + "\r\n");
   SendMessage (m_sockClient, "Proxy-Connection: close" + "\r\n");
   SendMessage (m_sockClient, "\r\n");
   SendMessage (m_sockClient, status + " " + strReason);
   SendMessage (m_sockClient, strText);
  }
  // Send a string to a socket.
  void SendMessage (Socket sock, string strMessage)
  {
   buffer = new Byte [strMessage.Length + 1];
   int len = ASCII.GetBytes (strMessage.ToCharArray(),
          0, strMessage.Length, buffer, 0);
   sock.Send (buffer, len, 0);
  }
  // Read a string from a socket.
  int ReadMessage (Socket sock, byte [] buf, ref string strMessage)
  {
   int iBytes = sock.Receive (buf, 1024, 0);
   strMessage = Encoding.ASCII.GetString (buf);
   return (iBytes);
  }
 }
}

希望本文所述对大家的C#程序设计有所帮助。

时间: 2015-07-13

C#使用读写锁三行代码简单解决多线程并发的问题

在开发程序的过程中,难免少不了写入错误日志这个关键功能.实现这个功能,可以选择使用第三方日志插件,也可以选择使用数据库,还可以自己写个简单的方法把错误信息记录到日志文件. 选择最后一种方法实现的时候,若对文件操作与线程同步不熟悉,问题就有可能出现了,因为同一个文件并不允许多个线程同时写入,否则会提示"文件正在由另一进程使用,因此该进程无法访问此文件". 这是文件的并发写入问题,就需要用到线程同步.而微软也给线程同步提供了一些相关的类可以达到这样的目的,本文使用到的 System.Thr

C#如何对多线程、多任务管理(demo)

下面一段内容有项目需求有项目分析,通过一个小demo给大家展示下C#如何对多线程.多任务管理的. 项目需求:假设多个任务需要执行,每个任务不是一时半会能完成(需要能看到中间执行状况): 多个任务 根据条件不同 可能需要不同的处理 项目分析: 多线程并发执行多任务: 对任务进行管理,追踪中间执行状态: 运用策略模式抽象执行类: public enum TaskStatus { wait = 0, working = 1, stop = 2, suspend = 3, complete = 4, f

C#实现向多线程传参的三种方式实例分析

本文实例讲述了C#实现向多线程传参的三种方式.分享给大家供大家参考,具体如下: 从<C#高级编程>了解到给线程传递参数有两种方式,一种方式是使用带ParameterizedThreadStart委托参数的Thread构造函数,另一种方式是创建一个自定义类,把线程的方法定义为实例的方法,这样就可以初始化实例的数据,之后启动线程. 方式一:使用ParameterizedThreadStart委托 如果使用了ParameterizedThreadStart委托,线程的入口必须有一个object类型的

C#使用Parallel类进行多线程编程实例

本文实例讲述了C#使用 Parallel 类进行多线程编程的方法.分享给大家供大家参考.具体如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Diagnostics; using System.Runtime.InteropServic

C#解决SQlite并发异常问题的方法(使用读写锁)

本文实例讲述了C#解决SQlite并发异常问题的方法.分享给大家供大家参考,具体如下: 使用C#访问sqlite时,常会遇到多线程并发导致SQLITE数据库损坏的问题. SQLite是文件级别的数据库,其锁也是文件级别的:多个线程可以同时读,但是同时只能有一个线程写.Android提供了SqliteOpenHelper类,加入Java的锁机制以便调用.但在C#中未提供类似功能. 作者利用读写锁(ReaderWriterLock),达到了多线程安全访问的目标. using System; usin

解析C#多线程编程中异步多线程的实现及线程池的使用

0.线程的本质 线程不是一个计算机硬件的功能,而是操作系统提供的一种逻辑功能,线程本质上是进程中一段并发运行的代码,所以线程需要操作系统投入CPU资源来运行和调度. 1.多线程: 使用多个处理句柄同时对多个任务进行控制处理的一种技术.据博主的理解,多线程就是该应用的主线程任命其他多个线程去协助它完成需要的功能,并且主线程和协助线程是完全独立进行的.不知道这样说好不好理解,后面慢慢在使用中会有更加详细的讲解. 2.多线程的使用: (1)最简单.最原始的使用方法:Thread oGetArgThre

C#实现多线程写入同一个文件的方法

本文实例讲述了C#实现多线程写入同一个文件的方法.分享给大家供大家参考.具体实现方法如下: namespace WfpApp { public partial class Form2 : Form { object obj = new object(); public Form2() { InitializeComponent(); System.Threading.Thread thread; string[] users = new string[] { "zkk", "

C#实现多线程下载文件的方法

本文实例讲述了C#实现多线程下载文件的方法.分享给大家供大家参考.具体实现方法如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Threading; using System.Net; namespace WfpApp { public class MultiDownload { #region 变量 pri

如何使用C#读写锁ReaderWriterLockSlim

读写锁的概念很简单,允许多个线程同时获取读锁,但同一时间只允许一个线程获得写锁,因此也称作共享-独占锁.在C#中,推荐使用ReaderWriterLockSlim类来完成读写锁的功能. 某些场合下,对一个对象的读取次数远远大于修改次数,如果只是简单的用lock方式加锁,则会影响读取的效率.而如果采用读写锁,则多个线程可以同时读取该对象,只有等到对象被写入锁占用的时候,才会阻塞. 简单的说,当某个线程进入读取模式时,此时其他线程依然能进入读取模式,假设此时一个线程要进入写入模式,那么他不得不被阻塞

C#基于委托实现多线程之间操作的方法

本文实例讲述了C#基于委托实现多线程之间操作的方法.分享给大家供大家参考,具体如下: 有的时候我们要起多个线程,更多的时候可能会有某个线程会去操作其他线程里的属性. 但是线程是并发的,一般的调用是无法实现我们的要求的. 于是,我们在这里就可以用委托,代码如下 private delegate void DelegateInfo(); private delegate void DelegateIsEnd(); //这个是线程调用其他线程的方法 private void Dowork() { //

基于easyui checkbox 的一些操作处理方法

1.获取已勾选的行: var rows = $('#datagrid').datagrid('getChecked'); 2.判断checkbox是否全选: var allFlg = $(".datagrid-header-check").find("input").is(":checked"); 3.checkbox在弹出层的,记住选中的checkbox,再次弹出弹出层时,将已选的checkbox回设 先将已选的checkbox该行的idFie

winform基于异步委托实现多线程摇奖器

本文实例讲述了winform基于异步委托实现多线程摇奖器.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using Sys

Java基于jdbc连接mysql数据库操作示例

本文实例讲述了Java基于jdbc连接mysql数据库操作.分享给大家供大家参考,具体如下: import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class MySQLDemo { private Connection conn = null; pri

PHP基于迭代实现文件夹复制、删除、查看大小等操作的方法

本文实例讲述了PHP基于迭代实现文件夹复制.删除.查看大小等操作的方法.分享给大家供大家参考,具体如下: 前面一篇 PHP递归实现文件夹的复制.删除.查看大小操作 分析了递归操作使用技巧,这里再来分析一下迭代的操作技巧. "既然递归能很好的解决,为什么还要用迭代呢"?主要的原因还是效率问题-- 递归的概念是函数调用自身,把一个复杂的问题分解成与其相似的多个子问题来解决,可以极大的减少代码量,使得程序看起来非常优雅. 由于系统要为每次函数调用分配运行空间,并使用压栈予以记录.在函数调用结

Android基于Intent实现Activity之间数据传递的方法

本文实例讲述了Android基于Intent实现Activity之间数据传递的方法.分享给大家供大家参考,具体如下: MainActivity: package com.test.intentdemo; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.Menu; import andro

Python基于ThreadingTCPServer创建多线程代理的方法示例

本文实例讲述了Python基于ThreadingTCPServer创建多线程代理的方法.分享给大家供大家参考,具体如下: #coding=utf8 from BaseHTTPServer import BaseHTTPRequestHandler from SocketServer import ThreadingTCPServer import gzip from StringIO import StringIO import logging logging.basicConfig(level

详解python多线程之间的同步(一)

引言: 线程之间经常需要协同工作,通过某种技术,让一个线程访问某些数据时,其它线程不能访问这些数据,直到该线程完成对数据的操作.这些技术包括临界区(Critical Section),互斥量(Mutex),信号量(Semaphore),事件Event等. Event threading库中的event对象通过使用内部一个flag标记,通过flag的True或者False的变化来进行操作.      名称                                      含义 set( )

两台服务器之间无密码传输数据和操作的方法

我们知道如果要向远程服务器传输数据和操作必须输入用户名和密码远程登录服务器 ,或用FTP等协议,都需要权限控制. 然而如果是两台服务器间的软件需要通讯和数据传输,如hadoop集群中机器互访,是不是每次也要输入用户名和密码?那是不是很麻烦?下面介绍SSH来解决这个问题(不是JAVA中的SSH概念) SSH是一种网络协议,用于计算机之间的加密登录. 如果一个用户从本地计算机,使用SSH协议登录另一台远程计算机,我们就可以认为,这种登录是安全的,即使被中途截获,密码也不会泄露. 最早的时候,互联网通

基于javascript的COOkie的操作实现只能点一次

我知道很多人在网站开发的时候其实需要这个功能的,就是控制用户一直点顶什么的!所以我在这里简单写一下,基于javascript的COOkie的操作! 复制代码 代码如下: //设置cookie function setCookie(key, value) {         document.cookie = key + "=" + escape(value); } //获取cookie的值     function getCookie(key) {         if (docume