关于.net里面的socket知识 C# socket详解

.NET\u5e73\u53f0\u4e0b\u51e0\u79cdSOCKET\u6a21\u578b\u7684\u7b80\u8981\u6027\u80fd\u4f9b\u53c2\u8003

1.Socket + Threads/ThreadPool\u5927\u6982\u6027\u80fd\uff1a\u5c0f\u4e8e1500\u4e2a\u8fde\u63a5 \u5b9e\u73b0\uff1aAccept\u4e00\u4e2aSocket\uff0c\u5c31\u4ea4\u7ed9\u4e00\u4e2a\u7ebf\u7a0b\u53bb\u7ba1\u7406\uff0c\u6bd4\u8f83\u7b28\uff0c\u4f46\u4e5f\u6bd4\u8f83\u6709\u6548\uff0c\u56e0\u4e3a\u662f\u540c\u6b65\u65b9\u5f0f\uff0c\u63a7\u5236\u8d77\u6765\u5f88\u65b9\u4fbf\u3002\u9ad8\u7ea7\u70b9\u7684\uff0c\u5c31\u662f\u4ea4\u7ed9\u4e00\u4e2a\u7ebf\u7a0b\u6c60\u53bb\u7ba1\u7406\uff0c\u7ebf\u7a0b\u6c60\u7531\u7cfb\u7edf\u81ea\u52a8\u6258\u7ba1\uff0c\u7701\u53bb\u4e86\u5f00\u9500\u7ebf\u7a0b\u7684\u65f6\u95f4\u3002\u4e00\u822c\u5c0f\u578b\u9879\u76ee\uff0c\u7528\u8fd9\u4e2a\u5b8c\u5168\u8db3\u591f\uff0c\u5f00\u53d1\u4e5f\u7b80\u5355\u3002\u4f46\u8981\u6ce8\u610f\uff0c\u5982\u679c\u82e5\u5e72Socket\u957f\u65f6\u95f4\u5360\u7528\u7ebf\u7a0b\u6c60\u4e2d\u7684\u7ebf\u7a0b\uff0c\u540c\u65f6\u5176\u5b83\u8fde\u63a5\u6570\u53c8\u6bd4\u8f83\u591a\uff0c\u5f88\u5bb9\u6613\u51fa\u73b0\u63d0\u793a\u8bf4\u4f60\u6ca1\u6709\u8db3\u591f\u7684\u7ebf\u7a0b\u4f9b\u4f7f\u7528\u3002\u5475\u5475\uff0c\u8ba9Socket\u5c11\u505a\u70b9\u4e8b\uff0c\u5c11\u5360\u7528\u65f6\u95f4\uff0c\u6362\u4e00\u4e2a\u5feb\u70b9\u7684CPU\u662f\u4e0d\u9519\u7684\u65b9\u5f0f\u3002\u53e6\u5916\uff0c\u5982\u679c\u6709\u4e00\u4e9b\u6bd4\u8f83\u597d\u7684\u7b2c\u4e09\u65b9\u7ebf\u7a0b\u6c60\u7ec4\u4ef6\uff0c\u4e5f\u53ef\u4ee5\u9009\u62e9\u4f7f\u7528\uff0c\u6bd4\u5982SmartThreadPool\u30022.Socket + Select\u5927\u6982\u6027\u80fd\uff1a\u5927\u4e8e1500\u4e2a\u8fde\u63a5\u540e\u6027\u80fd\u4e0b\u964d \u5b9e\u73b0\uff1aSelect\u662f\u5f88\u5e38\u7528\u7684\u4e00\u79cd\u6a21\u578b\u3002\u662f\u5728\u963b\u585e\u529f\u80fd\u4e2d\u8f6e\u8be2\u4e00\u4e2a\u6216\u591a\u4e2aSocket\uff0c\u5c06\u8981\u5904\u7406\u7684Socket\u653e\u5230\u4e00\u4e2aIList\u4e2d\uff0c\u5f53Select\u8f6e\u8be2\u7ed3\u675f\u540e\uff0c\u7136\u540e\u6211\u4eec\u518d\u81ea\u5df1\u5904\u7406\u8fd9\u4e2aIList\u4e2d\u7684Socket\u3002\u5177\u4f53\u7684\u7528\u6cd5\u53ef\u4ee5\u770b\u4e00\u4e0bMSDN\u3002Select\u7684\u6548\u7387\u5e76\u4e0d\u80fd\u8bf4\u662f\u9ad8\u7684\uff0c\u56e0\u4e3a\u5f53\u961f\u5217\u4e2d\u5f85\u5904\u7406\u7684Socket\u6bd4\u8f83\u591a\u7684\u65f6\u5019\uff0c\u5904\u7406\u6700\u540e\u51e0\u4e2aSocket\u76f8\u5f53\u4e8e\u8981\u904d\u5386\u6240\u6709\u524d\u9762\u7684Socket\uff0c\u975e\u5e38\u4e0d\u5212\u7b97\u7684.3.Socket + Asynchronous\u5927\u6982\u6027\u80fd\uff1a\u7ea67500\u4e2a\u5ba2\u6237\u7aef\u8fde\u63a5 \u5b9e\u73b0\uff1aBeginXXXX\uff0cEndXXXX\uff0c\u518d\u719f\u6089\u4e0d\u8fc7\u4e86\u5427\u3002\u5f02\u6b65Socket\u5f52\u6839\u5230\u5e95\uff0c\u8fd8\u662f\u7528\u7684\u7ebf\u7a0b\u6c60\u6280\u672f\uff0c\u7528\u7ebf\u7a0b\u6c60\u6765\u5904\u7406\u5f02\u6b65IO\u3002\u8fd9\u5c31\u53c8\u5f15\u51fa\u4e2a\u95ee\u9898\uff0c.NET\u7684\u7ebf\u7a0b\u6c60\u53c8\u662f\u7528\u7684\u4ec0\u4e48\u5b9e\u73b0\u65b9\u5f0f\uff0c\u4ee5\u524d\u770b\u8fc7\u6709\u4eba\u8bf4\uff0c.NET\u7684\u7ebf\u7a0b\u6c60\u662f\u7528\u7684\u5b8c\u6210\u7aef\u53e3\u6765\u5b9e\u73b0\u7684\uff0c\u6211\u4e0d\u77e5\u9053\u8fd9\u6837\u7684\u8bf4\u6cd5\u662f\u4e0d\u662f\u6b63\u786e\uff0c\u4ece\u67e5\u5230\u7684\u8d44\u6599\u4e2d\u4e5f\u6ca1\u6709\u529e\u6cd5\u786e\u8ba4\uff08\u5e0c\u671b\u8fd9\u70b9\u6709\u670b\u53cb\u53ef\u4ee5\u544a\u8bc9\u6211\uff09\u3002\u5f02\u6b65Socket\u5bf9\u4e8e\u7a0b\u5e8f\u7684\u5904\u7406\u6d41\u7a0b\u6765\u8bf4\u6bd4\u540c\u6b65\u590d\u6742\u4e86\u8bb8\u591a\uff0c\u5f02\u6b65\u56de\u8c03\u51fd\u6570\u7684\u63a7\u5236\u4e0d\u5982\u540c\u6b65\u65b9\u5f0f\u90a3\u6837\u76f4\u89c2\u3002\u4f46\u6709\u4e00\u70b9\u6211\u60f3\u5e94\u8be5\u662f\u8981\u6ce8\u610f\u7684\uff0c\u5c31\u662f\u56de\u8c03\u51fd\u6570\u5e94\u8be5\u8f7b\u88c5\u4e0a\u9635\uff0c\u4e0d\u5e94\u8be5\u5904\u7406\u8fc7\u591a\u7684\u4e8b\u52a1\uff0c\u5bf9\u4f20\u9012\u6570\u636e\u7684\u5904\u7406\uff0c\u5e94\u8be5\u4ea4\u7ed9\u5176\u5b83\u7ebf\u7a0b\u8fdb\u884c\u5904\u7406\u3002 4.IOCP\uff08\u5b8c\u6210\u7aef\u53e3\uff09\u5927\u6982\u6027\u80fd\uff1a\u7ea620000~50000\u4e2a\u5ba2\u6237\u7aef\u8fde\u63a5 \u5b9e\u73b0\uff1a\u73b0\u5728.NET\u4e0b\u6709\u4e00\u4e9b\u4f2aIOCP\uff0c\u5927\u5bb6\u53ef\u4ee5\u53bb\u641c\u7d22\u4e00\u4e0b\uff0c\u8fd8\u6ca1\u6709\u89c1\u8fc7\u5f00\u653e\u51fa\u6765\u7684\u7528\u8fd9\u4e9b\u4f2aIOCP\u6765\u5b9e\u73b0\u7684SOCKET\u4f8b\u5b50\u3002\u6211\u8bf4\u768420000~50000\u4e2a\u5ba2\u6237\u7aef\u8fde\u63a5\uff0c\u662f\u6307\u5728C++\u4e0b\u5f00\u53d1\u7684\u60c5\u51b5\uff0c\u8fd9\u6837\u7684\u60c5\u51b5\u4e0b\uff0c\u9700\u8981\u7528\u5230\u7684\u57fa\u672c\u6280\u672f\u8fd8\u5305\u62ec\u5185\u5b58\u6c60\u3001\u67e5\u8be2\u7b97\u6cd5\u7b49\u3002\u4f2aIOCP\u80fd\u5b9e\u73b0\u591a\u5c11\u6700\u5927\u8fde\u63a5\uff0c\u6ca1\u6709\u8d44\u6599\u53ef\u4ee5\u67e5\uff0c\u5982\u679c\u6709\u670b\u53cb\u77e5\u9053\uff0c\u53ef\u4ee5\u8ba8\u8bba\u4e00\u4e0b\u3002\u53e6\u5916\u4e0a \u9762\u63d0\u5230\u7684\u8bb8\u591a\u6570\u636e\uff0c\u662f\u4ece\u4e00\u4e9b\u8d44\u6599\u4e0a\u6458\u6284\u4e0b\u6765\u7684\uff0c\u6211\u6ca1\u6709\u81ea\u5df1\u8bd5\u8fc7\uff0c\u4ec5\u4ec5\u662f\u62ff\u51fa\u6765\u548c\u5927\u5bb6\u8ba8\u8bba\u4e00\u4e0b\u30021. Introduction - Native Win32 IOCPI/O Completion Ports (IOCP) supported on Microsoft Windows platforms has two facets. It first allows I/O handles like file handles, socket handles, etc., to be associated with a completion port. Any async I/O completion event related to the I/O handle associated with the IOCP will get queued onto this completion port. This allows threads to wait on the IOCP for any completion events. The second facet is that we can create a I/O completion port that is not associated with any I/O handle. In this case, the IOCP is purely used as a mechanism for efficiently providing a thread-safe waitable queue technique. This technique is interesting and efficient. Using this technique, a pool of a few threads can achieve good scalability and performance for an application. Here is a small example. For instance, if you are implementing a HTTP server application, then you need to do the following mundane tasks apart from the protocol implementation:Create a client connection listen socket. Once we get the client connection, use the client socket to communicate with the client to and fro. You can implement it by creating one dedicated thread per client connection that can continuously communicate with the client to and fro. But this technique quickly becomes a tremendous overhead on the system, and will reduce the performance of the system as the number of simultaneous active client connections increase. This is because, threads are costly resources, and thread switching is the major performance bottle neck especially when there are more number of threads.The best way to solve this is to use an IOCP with a pool of threads that can work with multiple client connections simultaneously. This can be achieved using some simple steps...Create a client connection listen socket. Once we get the client connection, post an IOCP read message on the socket to an IOCP. One of the threads waiting for completion events on this IOCP will receive the first read message for the client. It immediately posts another read onto the same IOCP and continues processing the read message it got. Once processing the read message is completed, it again waits on the IOCP for another event. This technique will allow a small pool of threads to efficiently handle communication with hundreds of client connections simultaneously. Moreover, this is a proven technique for developing scalable server side applications on Windows platforms.The above is a simplified description of using IOCP in multithreaded systems. There are some good in-depth articles on this topic in CodeProject and the Internet. Do a bit of Googling on words like IO Completion Ports, IOCP, etc., and you will be able to find good articles.2. Introduction - Managed IOCPManaged IOCP is a small .NET class library that provides the second facet of Native Win32 IOCP. This class library can be used both by C# and VB.NET applications. I chose the name Managed IOCP to keep the readers more close to the techniques they are used to with native Win32 IOCP. As the name highlights, Managed IOCP is implemented using pure .NET managed classes and pure .NET synchronization primitives. At its core, it provides a thread-safe object queuing and waitable object receive mechanism. Apart from that, it provides a lot more features. Here is what it does:Multiple Managed IOCP instances per process. Registration of multiple threads per Managed IOCP instance. Dispatching System.Object types to a threadsafe queue maintained by each Managed IOCP instance. Waitable multi-thread safe retrieval of objects from the Managed IOCP instance queue by all the threads registered for that particular Managed IOCP instance. Ability to restrict the number of concurrent active threads processing the queued objects related to a particular Managed IOCP instance. Policy based replaceable/customizable approach for choosing a registered thread to process the next available queued object. Ability to pause the Managed IOCP processing. Internally, pauses processing of queued objects by registered threads. Also, by default, disallows enqueuing new objects (can be changed). Run the Managed IOCP instance. Internally re-starts the processing of queued objects by registered threads. Also allows enqueuing new objects (if it is disallowed previously). Modify the max. allowed concurrent threads at runtime. Provides easy accessibility to Managed IOCP instance runtime properties like... Number of active concurrent threads. Number of objects left in queue. Number of allowed concurrent threads. Running status. Safe and controlled closing of a Managed IOCP instance. 2.1. Managed IOCP in Job/Task Oriented Business ProcessesManaged IOCP can be used in other scenarios apart from the sample that I mentioned in the introduction to native Win32 IOCP. It can be used in process oriented server side business applications. For instance, if you have a business process ( _not_ a Win32 process) with a sequence of tasks that will be executed by several clients, you will have to execute several instances of the business process, one for each client in parallel. As mentioned in my introduction to native Win32 IOCP, you can achieve this by spawning one dedicated thread per business process instance. But the system will quickly run out of resources, and the system/application performance will come down as more instances are created. Using Managed IOCP, you can achieve the same sequential execution of multiple business process instances, but with fewer threads. This can be done by dispatching each task in a business process instance as an object to Managed IOCP. It will be picked up by one of the waiting threads and will be executed. After completing the execution, the thread will dispatch the next task in the business process instance to the same Managed IOCP, which will be picked up by another waiting thread. This is a continuous cycle. The advantage is that you will be able to achieve the sequential execution goal of a business process, as only one waiting thread can receive a dispatched object, and at the same time keep the system resource utilization to required levels. Also, the system and business process execution performance will increase as there are few threads executing multiple parallel business processes.3. Using Managed IOCP in .NET applicationsMultithreaded systems are complex in the context that most problems will show up in real time production scenarios. To limit the possibility of such surprises while using Managed IOCP, I created a test application using which several aspects of the Managed IOCP library can be tested. Nevertheless, I look forward for any suggestions/corrections/inputs to improve this library and its demo application.Before getting into the demo application, below is the sequence of steps that an application would typically perform while using the Managed IOCP library:Create an instance of the ManagedIOCP class: 2. using Sonic.Net;ManagedIOCP mIOCP = new ManagedIOCP();The ManagedIOCP constructor takes one argument, concurrentThreads. This is an integer that specifies how many maximum concurrent active threads are allowed to process objects queued onto this instance of ManagedIOCP. I used a no argument constructor, which defaults to a maximum of one concurrent active thread.From a thread that needs to wait on objects queued onto the ManagedIOCP instance, call the Register() method on the ManagedIOCP instance. This will return an instance of the IOCPHandle class. This is like native Win32 IOCP handle, using which the registered thread can wait on the arrival of objects onto the ManagedIOCP instance. This thread can use the Wait() method on the IOCPHandle object. The Wait() will indefinitely wait until it grabs an object queued onto the ManagedIOCP instance to which the calling thread is registered. It either comes out with an object, or an exception in case the ManagedIOCP instance is stopped (we will cover this later). 4. IOCPHandle hIOCP = mIOCP.Register();5. while(true)6. {7. try8. {9. object obj = hIOCP.Wait();10. // Process the object11. 12. }13. catch(ManagedIOCPException e)14. {15. break;16. }17. catch(Exception e)18. {19. break;20. }}Any thread (one that is registered with the ManagedIOCP instance and any non-registered thread) that has access to the ManagedIOCP instance can dispatch (Enqueue) objects to it. These objects are picked up by waiting threads that are registered with the ManagedIOCP instance onto which objects are being dispatched. 22. string str = "Test string";mIOCP.Dispatch(str);When a thread decides not to wait for objects any more, it should un-register with the ManagedIOCP instance. mIOCP.UnRegister();Once the application is done with an instance of ManagedIOCP, it should call the Close() method on it. This will release any threads waiting on this instance of ManagedIOCP, clears internal resources, and resets the internal data members, thus providing a controlled and safe closure of a ManagedIOCP instance. mIOCP.Close();There are certain useful statistics that are exposed as properties in the ManagedIOCP class. You can use them for fine tuning the application during runtime.// Current number of threads that are // concurrently processing the objects queued // onto this instance of Managed IOCP // (This is readonly property) int activeThreads = mIOCP.ActiveThreads;// Max number of concurrent threads // allowed to process objects queued onto this // instance of Managed IOCP (This is a read/write property) int concurThreads = mIOCP.ConcurrentThreads;// Current count of objects queued onto this Managed IOCP instance. // NOTE: This value may change very quickly // as multiple concurrent threads might // be processing objects from this instance of Managed IOCP queue. // So _do not_ depend on this value // for logical operations. Use this only for // monitoring purpose (Status reporting, etc.) // and during cleanup processes // (like not exiting main thread untill the queued object becomes 0, // i.e. no more objects to be processed, etc) // (This is readonly property) int qCount = mIOCP.QueuedObjectCount;// Number of threads that are registered with this instance of Managed IOCP // (This is readonly property) int regThreadCount = mIOCP.RegisteredThreads;3.1. Advanced usageFollowing are the advanced features of Managed IOCP that need to be used carefully.Managed IOCP execution can be paused at runtime. When a Managed IOCP instance is paused, all the threads registered with this instance of Managed IOCP will stop processing the queued objects. Also, if the 'EnqueueOnPause' property of the ManagedIOCP instance is false (by default, it is false), then no thread will be able to dispatch new objects onto the Managed IOCP instance queue. Calling Dispatch on the ManagedIOCP instance will throw an exception in the Pause state. If the 'EnqueueOnPause' property is set to true, then threads can dispatch objects onto the queue, but you need to be careful while setting this property to true, as this will increase the number of pending objects in the queue, thus occupying more memory. Also, when the Managed IOCP instance is re-started, all the registered threads will suddenly start processing a huge number of objects thus creating greater hikes in the system resource utilization.mIOCP.Pause();Once paused, the ManagedIOCP instance can be re-started using the Run method.mIOCP.Run();The running status of the Managed IOCP instance can be obtained using the IsRunning property:bool bIsRunning = mIOCP.IsRunning;You can retrieve the System.Threading.Thread object of the thread associated with the IOCPHandle instance, from its property named 'OwningThread'.3.2. Demo ApplicationI provided two demo applications with similar logic. The first is implemented using Managed IOCP, the other using native Win32 IOCP. These two demo applications perform the following steps:Create a global static ManagedIOCP instance or native Win32 IOCP. Create five threads. Each thread will dispatch one integer value at a time to the ManagedIOCP instance or native Win32 IOCP until the specified number of objects are completed. Start (creates a new set of five threads) and stop (closes the running threads) the object processing. The Sonic.Net (ManagedIOCP) demo application additionally demonstrates the following features of Managed IOCP that are unavailable in the Win32 IOCP:Pause and continue object processing during runtime. Change concurrent threads at runtime. Statistics like, Active Threads, Maximum Concurrent threads, Queued Objects Count and Running Status of Managed IOCP. Below is the image showing both the demo applications after their first cycle of object processing:Demo application resultsAs you can see in the above figure, Managed IOCP gives the same speed (slightly even better) as native Win32 IOCP. The goal of these two demo applications is _not_ to compare the speed or features of Win32 IOCP with that of Managed IOCP, but rather to highlight that Managed IOCP provides all the advantages of native Win32 IOCP (with additional features) but in a purely managed environment.I tested these two demo applications on a single processor CPU and a dual processor CPU. The results are almost similar, in the sense the Managed IOCP is performing as good as (sometimes performing better than) native Win32 IOCP.3.3. Source and demo application filesBelow are the details of the files included in the article's Zip file:Sonic.Net (folder) - I named this class library as Sonic.Net (Sonic stands for speed). The namespace is also specified as Sonic.Net. All the classes that I described in this article are defined within this namespace. The folder hierarchy is described below: 2. Sonic.Net3. |4. --> Assemblies5. |6. --> Solution Files7. |8. --> Sonic.Net9. |10. --> Sonic.Net Console Demo 11. |--> Sonic.Net Demo ApplicationThe Assemblies folder contains the Sonic.Net.dll (contains the ObjectPool, Queue, ManagedIOCP, IOCPHandle, and ThreadPool classes), Sonic.Net Demo Application.exe (demo application showing the usage of ManagedIOCP and IOCPHandle classes), and Sonic.Net Console Demo.exe (console demo application showing the usage of ThreadPool and ObjectPool classes).The Solution Files folder contains the VS.NET 2003 solution file for the Sonic.Net assembly project, Sonic.Net demo application WinForms project, and Sonic.Net console demo project.The Sonic.Net folder contains the Sonic.Net assembly source code.The Sonic.Net Console Demo folder contains the Sonic.Net console demo application source code. This demo shows the usage of the Managed IOCP ThreadPool, which is explained in my Managed I/O Completion Ports - Part 2 article. This demo uses a file that will be read by the ThreadPool threads. Please change the file path to a valid one on your system. The code below shows the portion in the code to change. This code is in the ManagedIOCPConsoleDemo.cs file.public static void ReadData(){ StreamReader sr = File.OpenText(@"C:\aditya\downloads\lgslides.pdf"); string st = sr.ReadToEnd(); st = null; sr.Close(); Thread.Sleep(100);}The Sonic.Net Demo Application folder contains the Sonic.Net demo application source code.Win32IOCPDemo (folder) - This folder contains the WinForms based demo application for demonstrating Win32 IOCP usage using PInvoke. When compiled, the Win32IOCPDemo.exe will be created in the Win32IOCPDemo\bin\debug or Win32IOCPDemo\bin\Release folder based on the current build configuration you selected. The default build configuration is set to Release mode. 4. Inside Managed IOCPThis section discusses the how and why part of the core logic that is used to implement Managed IOCP.4.1. Waiting and retrieving objects in Managed IOCPManaged IOCP provides a thread safe object dispatch and retrieval mechanism. This could have been achieved by a simple synchronized queue. But with synchronized queue, when a thread (thread-A) dispatches (enqueues) an object onto the queue, for another thread (thread-B) to retrieve that object, it has to continuously monitor the queue. This technique is inefficient as thread-B will be continuously monitoring the queue for arrival of objects, irrespective of whether the objects are present in the queue. This leads to heavy CPU utilization and thread switching in the application when multiple threads are monitoring the same queue, thus degrading the performance of the system.Managed IOCP deals with this situation by attaching an auto reset event to each thread that wants to monitor the queue for objects and retrieve them. This is why any thread that wants to wait on a Managed IOCP queue and retrieve objects from it has to register with the Managed IOCP instance using its 'Register' method. The registered threads wait for the object arrival and retrieve them using the 'Wait' method of the IOCPHandle instance. The IOCPHandle instance contains an AutResetEvent that will be set by the Managed IOCP instance when any thread dispatches an object onto its queue. There is an interesting problem in this technique. Let us say that there are three threads, thread-A dispatching the objects, and thread-B and thread-C waiting on object arrival and retrieving them. Now, say if thread-A dispatches 10 objects in its slice of CPU time. Managed IOCP will set the AutoResetEvent of thread-B and thread-C, thus informing them of the new object arrival. Since it is an event, it does not have an indication of how many times it has been set. So if thread-B and thread-C just wake up on the event set and retrieve one object each from the queue and again waits on the event, there would be 8 more objects left over in the queue unattended. Also, this mechanism would waste the CPU slice given to thread-B and thread-C as they are trying to go into waiting mode after processing a single object from the Managed IOCP queue.So in Managed IOCP, when thread-B and thread-C call the 'Wait' method on their respective IOCPHandle instances, the method first tries to retrieve an object from the Managed IOCP instance queue before waiting on its event. If it was able to successfully retrieve the object, it does

\u670d\u52a1\u5668\u7aef\u4ee3\u7801:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace ChatToolServer
{
public partial class Form1 : Form
{
//server-\u7528\u4e8e\u5904\u7406\u5ba2\u6237\u7aef\u8fde\u63a5\u8bf7\u6c42\u7684socket
Socket clientSocket = null;
delegate void del();

public Form1()
{
InitializeComponent();
}
//server-\u4fa6\u542c\u65b9\u6cd5
private void listen()
{
//\u83b7\u53d6\u670d\u52a1\u5668IP
string hostName = Dns.GetHostName();
IPAddress[] ip = Dns.GetHostAddresses(hostName);
IPAddress HostIp = ip[0];

//\u521b\u5efa\u4e00\u4e2a\u7f51\u7edc\u7aef\u70b9
IPEndPoint iep = new IPEndPoint(HostIp, 82);

//\u521b\u5efa\u670d\u52a1\u7aef\u670d\u52a1\u7aef\u5957\u63a5\u5b57
Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

//\u5c06\u5957\u63a5\u5b57\u4e0e\u7f51\u7edc\u7aef\u70b9\u7ed1\u5b9a
serverSocket.Bind(iep);

//\u5c06\u5957\u63a5\u5b57\u7f6e\u4e3a\u4fa6\u542c\u72b6\u6001\uff0c\u5e76\u8bbe\u7f6e\u6700\u5927\u961f\u5217\u6570\u4e3a10
serverSocket.Listen(10);

//\u4ee5\u540c\u6b65\u65b9\u5f0f\u4ece\u4fa6\u542c\u5957\u63a5\u5b57\u7684\u8fde\u63a5\u8bf7\u6c42\u961f\u5217\u4e2d\u63d0\u53d6\u7b2c\u4e00\u4e2a\u6302\u8d77\u7684\u8fde\u63a5\u8bf7\u6c42\uff0c\u7136\u540e\u521b\u5efa\u5e76\u8fd4\u56de\u65b0\u7684 Socket
//\u65b0\u7684\u5957\u63a5\u5b57\uff1a\u5305\u542b\u5bf9\u65b9\u8ba1\u7b97\u673a\u7684IP\u548c\u7aef\u53e3\u53f7\uff0c\u53ef\u4f7f\u7528\u8fd9\u4e2a\u5957\u63a5\u5b57\u4e0e\u672c\u673a\u8fdb\u884c\u901a\u4fe1
clientSocket = serverSocket.Accept();
if (clientSocket != null)
{
MessageBox.Show("\u8fde\u63a5\u6210\u529f\uff01");
}

}

private void send_Click(object sender, EventArgs e)
{
if (this.textBox1.Text != "")//\u4e0d\u80fd\u53d1\u9001\u7a7a\u6d88\u606f
{
try
{
//\u53d1\u9001\u6570\u636e
string message = textBox1.Text;
byte[] sendbytes = System.Text.Encoding.UTF8.GetBytes(message);
int successSendBtyes = clientSocket.Send(sendbytes, sendbytes.Length, SocketFlags.None);
}
catch (Exception exp)
{
MessageBox.Show(exp.Message);
}
//\u5c06\u53d1\u9001\u7684\u6570\u636e\u663e\u793a\u5230\u5bf9\u8bdd\u7a97\u53e3\u5e76\u4f7f\u5bf9\u8bdd\u7a97\u53e3\u7684\u6eda\u52a8\u6761\u4e00\u76f4\u505c\u7559\u5728\u6700\u4e0b\u65b9
this.textBox2.Text +="\u670d\u52a1\u5668:"+"\r\n" +textBox1.Text + "\r\n";//\u53d1\u5b8c\u4e00\u6761\u6d88\u606f\u5c31\u6362\u884c\u663e\u793a
this.textBox2.SelectionStart = this.textBox2.Text.Length;
this.textBox2.ScrollToCaret();
this.textBox1.Text = "";//\u5c06\u53d1\u9001\u7a97\u53e3\u6e05\u7a7a

}
else
{
MessageBox.Show("\u53d1\u9001\u5185\u5bb9\u4e0d\u80fd\u4e3a\u7a7a");
}

}

private void Form1_Load(object sender, EventArgs e)
{
//server-\u521b\u5efa\u5e76\u8fd0\u884c\u4fa6\u542c\u7ebf\u7a0b
Thread threadListen = new Thread(new ThreadStart(listen));
threadListen.Start();
}

private void timer1_Tick(object sender, EventArgs e)
{
byte[] receiveBytes = new byte[1024];
//\u5982\u679c\u4fa6\u542c\u540e\u53d6\u5f97\u5ba2\u6237\u7aef\u8fde\u63a5\uff0c\u5e76\u4e14\u5ba2\u6237\u7aef\u7684\u7f13\u51b2\u533a\u4e2d\u6709\u5185\u5bb9\u53ef\u8bfb,\u5f00\u59cb\u63a5\u6536\u6570\u636e
if (clientSocket != null)
{

if (clientSocket.Poll(100, SelectMode.SelectRead))
{
int successReceiveBytes = clientSocket.Receive(receiveBytes);
this.textBox2.Text += "\u5ba2\u6237\u7aef:" +"("+ clientSocket.RemoteEndPoint.ToString()+")"+"\r\n" +
System.Text.Encoding.UTF8.GetString(receiveBytes, 0, successReceiveBytes) + "\r\n";
this.textBox2.SelectionStart = this.textBox2.Text.Length;//\u4f7f\u5bf9\u8bdd\u7a97\u53e3\u7684\u6eda\u52a8\u6761\u4e00\u76f4\u505c\u7559\u5728\u6700\u4e0b\u65b9
this.textBox2.ScrollToCaret();
}

}
}
}
}

\u5ba2\u6237\u7aef\u4ee3\u7801;
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 ChatToolClient
{
public partial class Form1 : Form
{
Socket clientSocket = null;//\u5ba2\u6237\u7aef\u5957\u63a5\u5b57
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
try
{
//\u5efa\u7acb\u4e0e\u670d\u52a1\u5668\u8fde\u63a5\u7684\u5957\u63a5\u5b57
IPAddress ip = IPAddress.Parse("172.16.94.134");
IPEndPoint iep = new IPEndPoint(ip, 82);
clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect(iep);
textBox2.Text = "\u8fde\u63a5\u6210\u529f" + "\r\n";

}
catch (Exception exp)
{
MessageBox.Show(exp.Message);
}
}

private void send_Click(object sender, EventArgs e)
{

if (textBox1.Text != "")
{
try
{
//\u53d1\u9001\u6570\u636e
string message = textBox1.Text;
byte[] sendbytes = System.Text.Encoding.UTF8.GetBytes(message);
int successSendBtyes = clientSocket.Send(sendbytes, sendbytes.Length, SocketFlags.None);
}
catch (Exception exp)
{
MessageBox.Show(exp.Message);
}
//\u5c06\u53d1\u9001\u7684\u6570\u636e\u663e\u793a\u5230\u5bf9\u8bdd\u7a97\u53e3\u5e76\u4f7f\u5bf9\u8bdd\u7a97\u53e3\u7684\u6eda\u52a8\u6761\u4e00\u76f4\u505c\u7559\u5728\u6700\u4e0b\u65b9
this.textBox2.Text += "\u6211\u81ea\u5df1:"+"\r\n"+textBox1.Text + "\r\n";//\u53d1\u5b8c\u4e00\u6761\u6d88\u81ea\u5df1\u606f\u5c31\u6362\u884c\u663e\u793a
this.textBox2.SelectionStart = this.textBox2.Text.Length;
this.textBox2.ScrollToCaret();
this.textBox1.Text = "";//\u5c06\u53d1\u9001\u7a97\u53e3\u6e05\u7a7a
}
else
{
MessageBox.Show("\u53d1\u9001\u5185\u5bb9\u4e0d\u80fd\u4e3a\u7a7a");
}
}

private void timer1_Tick(object sender, EventArgs e)
{
byte[] receiveBytes = new byte[1024];
if (clientSocket.Poll(100, SelectMode.SelectRead))
{
int successReceiveBytes = clientSocket.Receive(receiveBytes);
this.textBox2.Text +="\u670d\u52a1\u5668:"+"\r\n"+
System.Text.Encoding.UTF8.GetString(receiveBytes, 0, successReceiveBytes) + "\r\n";
this.textBox2.SelectionStart = this.textBox2.Text.Length;//\u4f7f\u5bf9\u8bdd\u7a97\u53e3\u7684\u6eda\u52a8\u6761\u4e00\u76f4\u505c\u7559\u5728\u6700\u4e0b\u65b9
this.textBox2.ScrollToCaret();
}
}
}
}

\u53e6\u5916,\u672c\u4eba\u6709\u5f88\u591a\u81ea\u5df1\u5199\u7684Socket\u4ee3\u7801,\u5305\u62ecTCP,UDP.\u5e76\u4e14\u540c\u6b65,\u5f02\u6b65\u65b9\u6cd5\u7684\u90fd\u6709.\u9601\u4e0b\u9700\u8981\u7684\u8bdd,\u53ef\u4ee5\u8054\u7cfb\u672c\u4eba. E-mail:[email protected]

1.什么是socket
  所谓socket通常也称作"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。 以J2SDK-1.3为例,Socket和ServerSocket类库位于java .net包中。ServerSocket用于服务器端,Socket是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个Socket实例,操作这个实例,完成所需的会话。对于一个网络连接来说,套接字是平等的,并没有差别,不因为在服务器端或在客户端而产生不同级别。不管是Socket还是ServerSocket它们的工作都是通过SocketImpl类及其子类完成的。
重要的Socket API
  重要的Socket API:java .net.Socket继承于java.lang.Object,有八个构造器,其方法并不多,下面介绍使用最频繁的三个方法,其它方法大家可以见JDK-1.3文档。
  Accept方法用于产生"阻塞",直到接受到一个连接,并且返回一个客户端的Socket对象实例。"阻塞"是一个术语,它使程序运行暂时"停留"在这个地方,直到一个会话产生,然后程序继续;通常"阻塞"是由循环产生的。
  getInputStream方法获得网络连接输入,同时返回一个InputStream对象实例。
  getOutputStream方法连接的另一端将得到输入,同时返回一个OutputStream对象实例。 注意:其中getInputStream和getOutputStream方法均可能会产生一个IOException,它必须被捕获,因为它们返回的流对象,通常都会被另一个流对象使用。
2.如何开发一个Server-Client模型的程序
  开发原理:
  服务器,使用ServerSocket监听指定的端口,端口可以随意指定(由于1024以下的端口通常属于保留端口,在一些操作系统中不可以随意使用,所以建议使用大于1024的端口),等待客户连接请求,客户连接后,会话产生;在完成会话后,关闭连接。
  客户端,使用Socket对网络上某一个服务器的某一个端口发出连接请求,一旦连接成功,打开会话;会话完成后,关闭Socket。客户端不需要指定打开的端口,通常临时的、动态的分配一个1024以上的端口。
  Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。要学Internet上的TCP/IP网络编程,必须理解Socket接口。 Socket接口设计者最先是将接口放在Unix操作系统里面的。如果了解Unix系统的输入和输出的话,就很容易了解Socket了。网络的Socket数据传输是一种特殊的I/O,Socket也是一种文件描述符。Socket也具有一个类似于打开文件的函数调用Socket(),该函数返回一个整型的Socket描述符,随后的连接建立、数据传输等操作都是通过该Socket实现的。
常用的Socket类型
  有两种:流式Socket(SOCK_STREAM)和数据报式Socket(SOCK_DGRAM)。流式是一种面向连接的Socket,针对于面向连接的TCP服务应用;数据报式Socket是一种无连接的Socket,对应于无连接的UDP服务应用。 Socket建立为了建立Socket,程序可以调用Socket函数,该函数返回一个类似于文件描述符的句柄。socket函数原型为:int socket(int domain, int type, int protocol);domain指明所使用的协议族,通常为AF_INET,表示互联网协议族(TCP/IP协议族);type参数指定socket的类型:SOCK_STREAM 或SOCK_DGRAM,Socket接口还定义了原始Socket(SOCK_RAW),允许程序使用低层协议;protocol通常赋值0。Socket()调用返回一个整型socket描述符,你可以在后面的调用使用它。 Socket描述符是一个指向内部数据结构的指针,它指向描述符表入口。调用Socket函数时,socket执行体将建立一个Socket,实际上"建立一个Socket"意味着为一个Socket数据结构分配存储空间。 Socket执行体为你管理描述符表。两个网络程序之间的一个网络连接包括五种信息:通信协议、本地协议地址、本地主机端口、远端主机地址和远端协议端口。Socket数据结构中包含这五种信息。 socket在测量软件中的使用也很广泛



  • 鍏充簬.net閲岄潰鐨剆ocket鐭ヨ瘑
    绛旓細Socket寤虹珛涓轰簡寤虹珛Socket锛岀▼搴忓彲浠ヨ皟鐢⊿ocket鍑芥暟锛岃鍑芥暟杩斿洖涓涓被浼间簬鏂囦欢鎻忚堪绗︾殑鍙ユ焺銆俿ocket鍑芥暟鍘熷瀷涓猴細int socket(int domain, int type, int protocol);domain鎸囨槑鎵浣跨敤鐨勫崗璁棌锛岄氬父涓篈F_INET锛岃〃绀轰簰鑱旂綉鍗忚鏃忥紙TCP/IP鍗忚鏃忥級锛泃ype鍙傛暟鎸囧畾socket鐨绫诲瀷锛歋OCK_STREAM 鎴朣OCK_DGRAM锛孲ocket...
  • vb.netsocket瑙i櫎绔彛缁戝畾
    绛旓細1銆侀渶瑕佽幏鍙栧埌宸茬粡缁戝畾鍒扮壒瀹氱鍙g殑Socket瀵硅薄銆2銆侀氳繃璋冪敤Socket瀵硅薄鐨凜lose鏂规硶鏉ュ叧闂璖ocket杩炴帴锛岃繖灏嗘柇寮涓庣鍙g粦瀹氱殑鍏宠仈銆
  • .NET骞冲彴涓嬪嚑绉SOCKET妯″瀷鐨勭畝瑕佹ц兘渚涘弬鑰
    绛旓細IOCP锛堝畬鎴愮鍙o級澶ф鎬ц兘锛氱害20000~50000涓鎴风杩炴帴 瀹炵幇锛氱幇鍦.NET涓嬫湁涓浜涗吉IOCP锛屽ぇ瀹跺彲浠ュ幓鎼滅储涓涓嬶紝杩樻病鏈夎杩囧紑鏀惧嚭鏉ョ殑鐢ㄨ繖浜涗吉IOCP鏉ュ疄鐜鐨凷OCKET渚嬪瓙銆傛垜璇寸殑20000~50000涓鎴风杩炴帴锛屾槸鎸囧湪C++涓嬪紑鍙戠殑鎯呭喌锛岃繖鏍风殑鎯呭喌涓嬶紝闇瑕佺敤鍒扮殑鍩烘湰鎶鏈繕鍖呮嫭鍐呭瓨姹犮佹煡璇㈢畻娉曠瓑銆 浼狪OCP鑳藉疄鐜板灏...
  • VB.net涓叧浜巗ocket鐨鏁版嵁鎺ユ敹浜嬩欢,鎬庝箞鍐欏嚭鏉?璇︽儏瑙侀棶棰樿ˉ鍏卂鐧惧害鐭 ...
    绛旓細.NET 涓 Socket 鏄睘浜 System.Net.Sockets 杩欎釜鍛藉悕绌洪棿涓嬬殑锛岄涓诲彧鍏虫敞浜 Socket 绫绘湰韬紝鑰屽拷鐣ヤ簡鍏跺懡鍚嶇┖闂翠笅鐨勫叾浠栫被浜嗗惂锛烻ystem.Net.Sockets 涓嬫湁 TcpListener 绫伙紝瀹炰緥鍖栧苟 Start() 鍚庡嵆鍙惊鐜睛鍚寚瀹氱鍙g殑娑堟伅锛屾湁娑堟伅灏卞鐞嗭紝娌℃秷鎭氨缁х画寰幆绛夊緟銆傚弬鑰冪ず渚嬶細http://www.cnblogs.com/a...
  • 鍏充簬.Net鍜孷B6涓璖ocket鐨闂
    绛旓細Imports System.Net.Sockets Imports System.Text Public Class Client Public Shared Sub Main()Dim tcpc As New TCPClient()Dim read(35) As Byte Dim args As String() = Environment.GetCommandLineArgs()If (args.Length < 2) Then Console.WriteLine("璇峰湪鍛戒护琛涓鎸囧畾鏈嶅姟鍣ㄥ悕绉")Exit Sub...
  • vb.net涓璖ocket闂
    绛旓細1.缁戝畾鐨処P鏄湇鍔″櫒鐨処P鍦板潃锛屾湇鍔″櫒鏄浐瀹氱殑锛屽鎴风杩炴帴鐨勬槸涓涓凡鐭ョ殑鏈嶅姟鍣ㄧ銆2.瀹㈡埛绔殑璇濓紝杩炴帴鍒版湇鍔″櫒鏃讹紝鏈嶅姟鍣╝ccept鍚庯紝灏卞彲浠ヨ幏寰楀鎴风鐨勮繛鎺ヤ俊鎭紝鍖呮嫭IP鍦板潃鍜岀鍙c傛垜鏄C鐨勶紝鍦–璇█涓锛socket->bind->listen->accept->...锛屽湪accept鍑芥暟涓湁閫夐」锛屽涓媍addr缁撴瀯浣撲腑灏卞瓨鏈塧...
  • 濡備綍鐢.net.socket鍒涘缓涓涓湇鍔″櫒绔? .NET鎶鏈
    绛旓細涓嬮潰鐨勪唬鐮佺ず渚嬪垱寤 TcpListener銆倁sing System;using System.IO;using System.Net;using System.Net.Sockets;using System.Text;class MyTcpListener { public static void Main(){ TcpListener server=null;try { // Set the TcpListener on port 13000.Int32 port = 13000;IPAddress localAddr = ...
  • 鍏充簬vb.net涓璖ocket鐨闂
    绛旓細鍚屾椂涓轰粈涔堣鐢ㄤ笂闈㈢殑鏂规硶浼犲憿锛屽洜涓篤B.NET涓殑SOCKET鏈夊緢澶氶棶棰橈紝鎴戝氨涓烘鐑﹁繃锛屽洜涓鸿涓㈠寘锛堢悊璁轰笂TCP涓嶅瓨鍦級锛屾垨鑰呯矘鍖咃紝鎴栬呮柇鍖咃紝涔熷氨鏄綘鍦ㄦ帴鏀剁鑾峰彇鏂囦欢鏃舵暟鎹槸瑕佸嚭閿欑殑锛屾瘮濡備綘瀹氶暱3000B锛岀粨鏋滄帴鏀剁鍙兘鍏堟敹鍒2000B锛屽綋鎺ュ彈绔帴鍙楀悗锛屽鐞嗕細鍑洪敊鐨勩傛墍浠OCKET鐨勬爣鍑嗗彂閫佹柟娉曟槸寤虹珛瀹氶暱鐨...
  • net.Socket鎬庢牱涓诲姩鏂紑鏌愪釜瀹㈡埛绔殑杩炴帴
    绛旓細浣跨敤Socket绫涓殑Poll鏂规硶锛屽氨鍙互銆係ocket client //鍋囧宸茬粡鍒涘缓濂戒簡锛岃繛鎺ュ埌鏈嶅姟鍣ㄧ寰Socket鐨瀹㈡埛绔璞°傛垜浠彧瑕乧lient.Poll(10,SelectMode.SelectRead)鍒ゆ柇灏辫浜嗐傚彧瑕佽繑鍥濼rue鏄傚氨鍙互璁や负瀹㈡埛绔凡缁忔柇寮浜嗐侾oll 鏂规硶灏嗕細妫鏌 Socket 鐨鐘舵併傛寚瀹 selectMode 鍙傛暟鐨 SelectMode..::.Select...
  • .NET涓嬩娇鐢Socket杩涜TCP浼犺緭鏃舵暟鎹彂閫佹垨鎺ユ敹涓嶅叏
    绛旓細璇曚笅寮曞叆澶氱嚎绋嬪惂.璁╂湇鍔″櫒杩斿洖涓涓俊鎭, 鍛婅瘔瀹㈡埛绔彲浠ュ紑濮嬩紶鏁版嵁涔嬪悗, 瀹㈡埛绔啀浼, 涔嬪墠鏈嶅姟鍣ㄧ寮涓涓嚎绋嬫潵鎺ユ敹鏁版嵁.浣犺繕鍙互妫娴嬫敹鍒扮殑1W8鏁版嵁鏄3W8閲岄潰鐨鍝竴閮ㄥ垎. 杩欎釜鎶婂彂閫佺殑鏁版嵁鍜屾帴鏀剁殑鏁版嵁閮戒繚瀛樻垚鏂囦欢, 鐒跺悗鐢╓inHex鎵撳紑灏辫兘寰堝鏄撴煡鎵惧埌. 杩欐牱鎵嶇煡閬撲涪鐨勬槸鍝儴鍒, 鐒跺悗鎸夋儏鍐靛鐞.
  • 扩展阅读:xbox series x ... paperpass免费入口 ... java blockingqueue ... jack jones ... 韩国macbookpro ... visual studio code ... java windowbuilder ... gopro hero11 black ... summer pocketsrb ...

    本站交流只代表网友个人观点,与本站立场无关
    欢迎反馈与建议,请联系电邮
    2024© 车视网