2011-03-16 13 views
6

के साथ सहायता मैं एक "एप्लिकेशन सिस्टम" पर काम कर रहा हूं, जहां मुझे सर्वर एप्लिकेशन बनाने की भी आवश्यकता है। मैं सी # (.NET 4.0) में काम कर रहा हूं। सर्वर मुख्य रूप से विभिन्न पीओएस अनुप्रयोगों/ग्राहकों से डेटा एकत्र करेगा (जो लगभग 50-100 होना चाहिए, लेकिन सर्वर 200-300 ग्राहकों को संभालने में सक्षम होना चाहिए)। एक ग्राहक से एक सर्वर को लगभग 1KB दिन में लगभग 100x बार प्राप्त होगा। सर्वर को मुख्य रूप से डेटा स्वीकार करने, इसे डिक्रिप्ट करने और डिस्क पर संग्रहीत करने की आवश्यकता होती है। ग्राहकों को नई कॉन्फ़िगरेशन भेजने के लिए इसे विशिष्ट निर्देशिका में परिवर्तनों की भी जांच करनी चाहिए, जो अक्सर नहीं होना चाहिए।ईवेंट संचालित टीसीपी सर्वर

मैं सी # और सर्वर प्रोग्रामिंग के लिए काफी नया हूं इसलिए कृपया मेरे साथ भालू। मैंने थ्रेडपूलिंग और एसिंक तरीकों का उपयोग करने के बारे में सोचा था (उसमें "सी # संक्षेप में" पुस्तक में इसका उपयोग करके एक अच्छा उदाहरण है। लेकिन मैं काफी समय के लिए सबसे अच्छा समाधान की तलाश में बिताता हूं और मुझे यह मिला। लेकिन मल्टीथ्रेडिंग मेरे मामले में लाभ की तुलना में अधिक समस्याएं लाती है। इस प्रकार मैंने सर्वर को भी संचालित करने के बारे में सोचा। "एक एकल प्रक्रिया, कॉलबैक पर प्रत्येक घटना (स्वीकृत कनेक्शन, पढ़ने के लिए उपलब्ध डेटा, क्लाइंट को लिख सकते हैं ...) को संभालती है।" "what is event driven web server" से। मुझे लगता है कि मेरी समस्या का सबसे अच्छा समाधान है।

लेकिन मुझे यह नहीं पता कि इसे कैसे कोड किया जाए, मुझे ईवेंट संचालित सर्वर के बारे में कोई उदाहरण नहीं मिला। जहां तक ​​मैं इसे समझता हूं, मुझे एक थ्रेड (जीयूआई के लिए + 1) बनाना चाहिए, फिर एक टीसीपी श्रोता बनाएं और फिर किसी भी तरह से ईवेंट बनाएं ताकि जब टीसीपी श्रोता ग्राहक को स्वीकार कर सके तो ईवेंट आग लग जाएगा और सर्वर को जगाएगा, जब डेटा ग्राहकों से पढ़ने के लिए उपलब्ध होगा यह सर्वर को जगाएगा।

कृपया इसे कोड करने में मेरी सहायता करें, मैं पूरी तरह से खो गया हूं। मुझे पता है कि मैं

while(true) 
{ 
    check if client wants to connect 
     accept client and add it to client list 
    iterate through client list and check if anyone is sending data ... 
     accept data and store it 
    ... 
    } 

का उपयोग करके यह कैसे कर सकता हूं लेकिन यह घटना संचालित नहीं है और सीपीयू बर्बाद कर रही है। सर्वर बहुत सक्रिय नहीं होगा, इसलिए मैं इसे यथासंभव कुशल बनाना चाहता हूं।

कुछ उदाहरण वास्तव में मदद करेंगे।

आपके समय और उत्तरों के लिए धन्यवाद।

पेज। क्या मैं सभी ग्राहकों के लिए सिर्फ एक बंदरगाह का उपयोग कर सकता हूं?

संपादित करें: स्पष्टीकरण के लिए, मैं एक ईवेंट संचालित सर्वर को कोड करना चाहता हूं, लेकिन मुझे नहीं पता कि कैसे, इस प्रकार मैंने केवल जो कुछ मुझे पता है (क्लाइंट मतदान) का उदाहरण दिया।

उत्तर

0

यहां आपको एक सर्वर कंकाल है जो आपको चाहिए। कोई अपवाद नहीं किया जाता है।

class Program 
{ 
    public static ManualResetEvent connected = new ManualResetEvent(false); 

    static void Main(string[] args) 
    { 
     string ip = "127.0.0.1"; 
     int port = 14500; 

     TcpListener server = new TcpListener(IPAddress.Parse(ip), port); 
     server.Start(); 

     Console.WriteLine("Server started..."); 

     while (true) 
     { 
      connected.Reset(); 
      server.BeginAcceptTcpClient(new AsyncCallback(AcceptCallback), server); 
      connected.WaitOne(); 
     } 
    } 

    public static void AcceptCallback(IAsyncResult ar) 
    { 
     TcpListener listener = (TcpListener)ar.AsyncState; 
     TcpClient client = listener.EndAcceptTcpClient(ar); 

     byte[] buffer = new byte[1024]; 
     NetworkStream ns = client.GetStream(); 
     if (ns.CanRead) 
     { 
      ns.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(ReadCallback), new object[] { ns, buffer }); 
     } 

     connected.Set(); 
    } 

    public static void ReadCallback(IAsyncResult ar) 
    { 
     NetworkStream ns = (NetworkStream)((ar.AsyncState as object[])[0]); 
     byte[] buffer = (byte[])((ar.AsyncState as object[])[1]); 
     int n = ns.EndRead(ar); 
     if (n > 0) 
     { 
      Console.WriteLine(Encoding.ASCII.GetString(buffer, 0, n)); 
     } 
     ns.BeginRead(buffer, 0, buffer.Length, new AsyncCallback(ReadCallback), new object[] { ns, buffer }); 
    } 
} 
+0

भयानक उदाहरण के साथ करना बहुत आसान है। यह रिमोट एंड (0 बाइट्स पढ़ने) से अपवाद या डिस्कनेक्ट को संभाल नहीं करता है। यह किसी एसिंक को किसी ईवेंट के साथ सिंक करने के लिए स्वीकार करता है, क्यों न केवल 'AcceptTcpClient' का उपयोग करें। एसिंक ऑपरेशंस में जादू संदर्भों का उपयोग न करें (आपके मामले में ऑब्जेक्ट सरणी में); – jgauffin

1

मुझे सी # ढांचे के बारे में पता नहीं है, लेकिन आप Twisted पर एक ईवेंट देख सकते हैं, जो एक पाइथन फ्रेमवर्क संचालित होता है। आप अपनी जरूरतों के समान, सर्वर और क्लाइंट कोड के उदाहरण पा सकते हैं।

पी.एस.:

#!/usr/bin/env python 

# Copyright (c) 2001-2009 Twisted Matrix Laboratories. 
# See LICENSE for details. 

from twisted.internet.protocol import Protocol, Factory 
from twisted.internet import reactor 

### Protocol Implementation 

# This is just about the simplest possible protocol 
class Echo(Protocol): 
    def dataReceived(self, data): 
     """ 
     As soon as any data is received, write it back. 
     """ 
     self.transport.write(data) 


def main(): 
    f = Factory() 
    f.protocol = Echo 
    reactor.listenTCP(8000, f) 
    reactor.run() 

if __name__ == '__main__': 
    main() 

आप आखिरी सवाल के बारे में:

यहाँ एक बहुत ही सरल सर्वर का एक नमूना है कि ग्राहक जो भी हो यह से प्राप्त करने के लिए वापस गूँज है क्या मैं सभी ग्राहकों के लिए सिर्फ एक बंदरगाह का उपयोग कर सकता हूं?

हाँ, आप (जो भी भाषा/ढांचे का उपयोग करते हैं) कर सकते हैं।

+0

+1 वाकई दिलचस्प लगता है। मैं सिर्फ मजेदार के लिए .NET संस्करण बनाने की कोशिश करने जा रहा हूं (जब मुझे समय मिल जाएगा;)) – jgauffin

+0

@jgauffin क्या आप इसे अंत में बंद कर देते हैं? – beppe9000

+0

@ बीपीपी 9 000: http://blog.gauffin.org/2012/05/04/griffin-networking-a-somply-performant-networking-library-for-net/। संस्करण 2 ग्रिफिन ढांचे में है: http://blog.gauffin.org/2014/05/30/griffin-framework-performant-networking-in-net/ – jgauffin

1

मैं एक विंडोज सेवा के रूप में होस्ट किए गए डब्ल्यूसीएफ का उपयोग करने का सुझाव दूंगा, जो एक स्केलेबल और मल्टीथ्रेड मंच प्रदान करता है। इसे प्रोटोकॉल आवश्यकता के अनुसार भी बनाया जा सकता है।

http://msdn.microsoft.com/en-us/library/ms733069.aspx

+0

डब्ल्यूसीएफ इसे बहुत ही जटिल बना देता है, अगर यू के पास कोई विकल्प है तो इसे लाओ। इसे tcplistener और async – Tom

1

संचालित घटना वास्तव में वर्णन नहीं है क्या आप अपने सिस्टम की तरह है क्योंकि आप मतदान के लिए अपने ग्राहकों डेटा अपने ग्राहकों के बजाय प्रक्रिया करने के लिए का वर्णन काम करने की उम्मीद: यहाँ एक उदाहरण है जो एक संदर्भ के रूप में इस्तेमाल किया जा सकता है अपने डेटा को अपनी सेवा में धक्का देना (एक ईवेंट ट्रिगर करना)।

यदि आपके पास इस तरह की प्रणाली को कोड करने के बारे में बहुत कम जानकारी है तो आप अपने परिदृश्य के लिए मौजूदा समाधान/उत्पादों को देख सकते हैं।

मैं पीओएस क्लाइंट को एकीकृत करने के लिए BlueIntegrator या BizTalk जैसे ईएआई टूल्स की जांच करने की सलाह दूंगा।

क्लाइंट अपडेट रोल करने से संबंधित आपकी आवश्यकता के लिए आप BITS देख सकते हैं।

3

सबसे पहले, यदि आप सी # और बहु ​​सूत्रण और सॉकेट के लिए नए हैं, कि एक बहुत अपनी पहली परियोजना के लिए काट रहा है। मैं इन्हें व्यक्तिगत रूप से सीखने की सलाह देता हूं।

उस ने कहा, आपको Nito.Async.Sockets सहायक मिल सकता है; इसमें एक इवेंट-संचालित सर्वर सॉकेट शामिल है और आपके लिए मल्टीथ्रेडिंग चिंताओं को संभालता है।

0

मैं पार्टी के लिए थोड़ा देर हो चुकी हूं, लेकिन मैंने हाल ही में वैज्ञानिक उपकरणों के साथ एकीकृत करने के लिए एक नया नौकरी विकसित करने वाला सॉफ्टवेयर शुरू किया है और वर्तमान में सीखने के थ्रेडिंग, कॉमम्स, एसिंक प्रोसेसिंग आदि के दर्द से गुजर रहा हूं। चीजों के थ्रेडिंग पक्ष के बारे में सीखने के लिए जो उत्कृष्टता के लिए जो उत्कृष्टता के लिए जो अल्बाहारी के Threading in C# को मिला है।

संबंधित मुद्दे