Point-to-peer is usually abbreviated as P2P. Point-to-point in a network can be viewed as a peer-to-peer network model. P2P is actually a technology that enables direct data exchange or service between different computers on the network without passing through relay devices. P2P allows any computer in the network to directly connect to other computers in the network and exchange data with it, which eliminates intermediate links, it also makes communication on the network easier and more direct.
As a network model, P2P is different from the traditional customer/server model. Customer/Server models generally have predefined clients and servers. There is no clear client or server in the P2P model, but in the P2P model, each computer can be regarded as either a server or a client. In the traditional Client/Server communication model, the computer that sends service requests or sends data is generally called a client, and the computer that receives, processes, or receives data is called a server. In the P2P network model, the computer not only receives data, but also sends data, not only service requests, but also service requests from the other party.
The LAN Point-to-point communication implemented using Visual C # is introduced belowProgramIt has the following features: Any computer that uses this communication program to communicate must listen on the port number before communication, accept the application for connection from other machines, and after the connection is established, you can receive the data sent by the other party. You can also submit a connection request to another machine and send the data to the other machine after the other computer allows the connection request to be established. It can be seen that any computer that uses this software in the network for P2P network communication is both a client and a server.
I. software environment for program design, debugging and operation:
(1). Microsoft Windows 2000 Server Edition
(2) Visual Studio. NET official version,. NET Framework SDK version 3705
2. Key Steps and solutions: the key step is to send and receive information in the network. Socket is used for data receiving, and networkstream is used for data sending.
1. Use SOCKET to receive information:
To clarify the problem, the program uses an inaccessible port number when processing data sending and receiving, and the default port number set by the data sending program is "8889 ". BelowCodeIs listening port number "8889", accept the connection request for this port number in the network, and after the connection is established, receive the data sent by the remote computer through socket:
Try
{
Tcplistener tllisten1 = new tcplistener (8889 );
// Listening port number
Tllisten1.start ();
Socket sksocket = tllisten1.acceptsocket ();
// Receive connection requests from remote computers and obtain the socket instance used to receive data
Endpoint tempremoteep = sksocket. remoteendpoint;
// Obtain the network remote endpoint corresponding to the remote computer
While (true)
{
Byte [] bystream = new byte [80];
// Define the data buffer zone for receiving data from a remote computer
Int I = sksocket. receivefrom (bystream, ref tempremoteep );
// Receives data and stores it in the defined buffer zone.
String smessage = system. Text. encoding. utf8.getstring (bystream );
// Parse the content from the buffer with the specified Encoding
MessageBox. Show (smessage );
// Display transmitted data
}
}
Catch (system. Security. securityexception)
{
MessageBox. Show ("firewall security error! "," Error ",
Messageboxbuttons. OK, messageboxicon. Exclamation );
}
2. Use networkstream to transmit information:
When streamwriter is used to process networkstream data transmission, the Data Transmission Encoding type is "utf8". The following Code applies for a connection to the "8888" Port Number of a computer whose IP address is "10.138.198.213, after the connection application is established, the UTF-8 encoded string "Hello, glad to meet you" is sent to the other party. Since the comments in the following code are more detailed, I will not introduce them here, the following code uses networkstream to transmit data:
Try
{
Tcpclient TCPC = new tcpclient ("10.138.198.213", 8888 );
// Apply for connection to port 8888 of the computer whose IP address is "10.138.198.213"
Networkstream tcpstream = TCPC. getstream ();
// If the connection request is established, the data stream used for data transmission is obtained.
}
Catch (exception)
{
MessageBox. Show ("the target computer rejects the connection request! ");
Break;
}
Try
{
String smsg = "Hello, glad to meet you ";
Streamwriter reqstreamw = new streamwriter (tcpstream );
// Write data to the data stream with a specific encoding. The default value is utf8 encoding.
Reqstreamw. Write (smsg );
// Write the string to the data stream
Reqstreamw. Flush ();
// Clear all the buffers of the current writer and write all the buffered data to the basic stream.
}
Catch (exception)
{
MessageBox. Show ("The message cannot be sent to the target computer! ");
}
Of course, when using Visual C # To implement point-to-point network communication programs, you must also have a lot of knowledge, such as the collection of resources. When you use Visual C # To write network applications, many of you may encounter this situation. After the program exits, the Windows "Resource Manager" shows that the number of processes has not decreased. This is because the threads used in the program may not exit effectively. Although the "Abort" method is provided in the Thread class to stop the process, it cannot guarantee a successful exit. Because some resources used in the process are not recycled. In some cases, the garbage collector cannot completely Recycle resources. We still need to manually Recycle resources. The procedure described in this article also involves the issue of manual resource recycling. For the implementation method, see Step 1 in the following implementation steps.
3. Specific steps:
After understanding and understanding the key issues and solutions, it is easier to use Visual C # To implement point-to-point network communication programs. The following describes the specific implementation steps:
1. Start Visual Studio. NET and create a new Visual C # project named [Visual C # network point-to-point communication program ].
2. In the Solution Explorer window of Visual Studio. NET integrated development environment, double-click the form1.cs file to enter the editing interface of the form1.cs file.
3. At the beginning of the form1.cs file, use the following imported namespace code to replace the default imported namespace code.
Using system;
Using system. drawing;
Using system. collections;
Using system. componentmodel;
Using system. Windows. forms;
Using system. Data;
Using system. net. Sockets;
Using system. net;
Using system. IO;
Using system. text;
Using system. Threading;
4. Switch the current window of Visual Studio. NET to the form1.cs window, and drag the following components into the form from the Windows Forms components tab in the toolbox:
Four button components, two ListBox components, four textbox components, one statusbar component, and five label components. After four button components are dragged into the form, double-click them on the form design interface, the system will generate the processing code corresponding to the click events of these four components in the form1.cs file.
5. In the Solution Explorer window, double-click the form1.cs file To Go To The form1.cs file editing page. The following code replaces the initializecomponent process generated by the system. The following code initializes the added component:
Private void initializecomponent ()
{
This. listbox1 = new system. Windows. Forms. ListBox ();
This. textbox1 = new system. Windows. Forms. Textbox ();
This. label3 = new system. Windows. Forms. Label ();
This. label2 = new system. Windows. Forms. Label ();
This. textbox3 = new system. Windows. Forms. Textbox ();
This. button1 = new system. Windows. Forms. Button ();
This. textbox2 = new system. Windows. Forms. Textbox ();
This. label1 = new system. Windows. Forms. Label ();
This. label4 = new system. Windows. Forms. Label ();
This. label5 = new system. Windows. Forms. Label ();
This. button2 = new system. Windows. Forms. Button ();
This. button3 = new system. Windows. Forms. Button ();
This. button4 = new system. Windows. Forms. Button ();
This. textbox4 = new system. Windows. Forms. Textbox ();
This. statusbar1 = new system. Windows. Forms. statusbar ();
This. statusbarpanel1 = new system. Windows. Forms. statusbarpanel ();
This. statusbarpanel2 = new system. Windows. Forms. statusbarpanel ();
This. label6 = new system. Windows. Forms. Label ();
This. listbox2 = new system. Windows. Forms. ListBox ();
(System. componentmodel. isupportinitialize)
(This. statusbarpanel1). begininit ();
(System. componentmodel. isupportinitialize)
(This. statusbarpanel2). begininit ();
This. suspendlayout ();
This. listbox1.itemheight = 12;
This. listbox1.location = new system. Drawing. Point (122,110 );
This. listbox1.name = "listbox1 ";
This. listbox1.size = new system. Drawing. Size (212, 88 );
This. listbox1.tabindex = 4;
This. textbox1.location = new system. Drawing. Point (122, 18 );
This. textbox1.name = "textbox1 ";
This. textbox1.size = new system. Drawing. Size (210, 21 );
This. textbox1.tabindex = 1;
This. textbox1.text = "";
This. label3.location = new system. Drawing. Point (220, 52 );
This. label3.name = "label3 ";
This. label3.size = new system. Drawing. Size (66, 23 );
This. label3.tabindex = 7;
This. label3.text = "local port :";
This. label2.location = new system. Drawing. Point (38, 54 );
This. label2.name = "label2 ";
This. label2.size = new system. Drawing. Size (80, 23 );
This. label2.tabindex = 20;
This. label2.text = "remote port :";
This. textbox3.location = new system. Drawing. Point (294, 50 );
This. textbox3.name = "textbox3 ";
This. textbox3.size = new system. Drawing. Size (38, 21 );
This. textbox3.tabindex = 3;
This. textbox3.text = "8889 ";
This. button1.flatstyle = system. Windows. Forms. flatstyle. Flat;
This. button1.location = new system. Drawing. Point (348, 16 );
This. button1.name = "button1 ";
This. button1.size = new system. Drawing. Size (92, 40 );
This. button1.tabindex = 6;
This. button1.text = "connect to a remote machine ";
This. button1.click + = new system. eventhandler (this. button#click );
This. textbox2.location = new system. Drawing. Point (122, 50 );
This. textbox2.name = "textbox2 ";
This. textbox2.size = new system. Drawing. Size (38, 21 );
This. textbox2.tabindex = 2;
This. textbox2.text = "8888 ";
This. label1.location = new system. Drawing. Point (38,22 );
This. label1.name = "label1 ";
This. label1.size = new system. Drawing. Size (80, 23 );
This. label1.tabindex = 16;
This. label1.text = "remote IP Address :";
This. label4.location = new system. Drawing. Point (50, 84 );
This. label4.name = "label4 ";
This. label4.size = new system. Drawing. Size (66, 23 );
This. label4.tabindex = 23;
This. label4.text = "sending message :";
This. label5.location = new system. Drawing. Point (36,112 );
This. label5.name = "label5 ";
This. label5.size = new system. Drawing. Size (80, 23 );
This. label5.tabindex = 24;
This. label5.text = "sent message :";
This. button2.enabled = false;
This. button2.flatstyle = system. Windows. Forms. flatstyle. Flat;
This. button2.location = new system. Drawing. Point (352,192 );
This. button2.name = "button2 ";
This. button2.size = new system. Drawing. Size (92, 40 );
This. button2.tabindex = 7;
This. button2.text = "Disconnect ";
This. button2.click + = new system. eventhandler (this. button2_click );
This. button3.flatstyle = system. Windows. Forms. flatstyle. Flat;
This. button3.location = new system. Drawing. Point (348, 74 );
This. button3.name = "button3 ";
This. button3.size = new system. Drawing. Size (92, 40 );
This. button3.tabindex = 8;
This. button3.text = "listening port ";
This. button3.click + = new system. eventhandler (this. button3_click );
This. button4.enabled = false;
This. button4.flatstyle = system. Windows. Forms. flatstyle. Flat;
This. button4.location = new system. Drawing. Point (350,132 );
This. button4.name = "button4 ";
This. button4.size = new system. Drawing. Size (92, 40 );
This. button4.tabindex = 9;
This. button4.text = "sending information ";
This. button4.click + = new system. eventhandler (this. button4_click );
This. textbox4.location = new system. Drawing. Point (122, 82 );
This. textbox4.name = "textbox4 ";
This. textbox4.size = new system. Drawing. Size (212, 21 );
This. textbox4.tabindex = 25;
This. textbox4.text = "";
This. statusbar1.location = new system. Drawing. Point (0,301 );
This. statusbar1.name = "statusbar1 ";
This. statusbar1.panels. addrange (new system. Windows. forms.
Statusbarpanel [] {
This. statusbarpanel1, this. statusbarpanel2 });
This. statusbar1.showpanels = true;
This. statusbar1.size = new system. Drawing. Size (456, 22 );
This. statusbar1.tabindex = 26;
This. statusbarpanel1.width = 200;
This. statusbarpanel2.width = 230;
This. label6.location = new system. Drawing. Point (48,210 );
This. label6.name = "label6 ";
This. label6.size = new system. Drawing. Size (66, 23 );
This. label6.tabindex = 28;
This. label6.text = "Receive information :";
This. listbox2.itemheight = 12;
This. listbox2.location = new system. Drawing. Point (122,206 );
This. listbox2.name = "listbox2 ";
This. listbox2.size = new system. Drawing. Size (214, 88 );
This. listbox2.tabindex = 27;
This. autoscalebasesize = new system. Drawing. Size (6, 14 );
This. clientsize = new system. Drawing. Size (456,323 );
This. Controls. addrange (new system. Windows. Forms. Control [] {
This. label6,
This. listbox2,
This. statusbar1,
This. textbox4,
This. button4,
This. button3,
This. button2,
This. label5,
This. label4,
This. label2,
This. textbox3,
This. button1,
This. textbox2,
This. label1,
This. label3,
This. textbox1,
This. listbox1 });
This. formborderstyle = system. Windows. Forms. formborderstyle.
Fixedsingle;
This. maximizebox = false;
This. Name = "form1 ";
This. Text = "Visual C # implement point-to-point network communication program ";
This. Load + = new system. eventhandler (this. form#load );
(System. componentmodel. isupportinitialize)
(This. statusbarpanel1). endinit ();
(System. componentmodel. isupportinitialize)
(This. statusbarpanel2). endinit ();
This. resumelayout (false );
}
Now, the interface design and function implementation of the [Visual C # network point-to-point communication program] project have been completed. Design Interface 1 is shown below:
Figure 1 project design page
6. In the Solution Explorer window, double-click the form1.cs file To Go To The form1.cs file editing page. Add the following code to the code area of the Form class member. The following code defines the global variables used in the program.
Private thread th;
// Create a thread to listen on the port number and receive information
Private tcplistener tllisten1;
// Listener port number
Private bool listenerrun = true;
// Set the flag to determine the listening status
Private networkstream tcpstream;
// Create a basic data stream instance for transmission/receipt
Private streamwriter reqstreamw;
// Send information to the remote host
Private tcpclient TCPC;
// Create a connection to the remote host
Private socket sksocket;
// Receives data sent from a remote host.
7. use the following code to replace the code corresponding to the "click" event of the button1 component in form1.cs. The following Code applies to a remote computer. If a connection is established, the data source that transmits the data is obtained:
Private void button#click (Object sender, system. eventargs E)
{
Try
{
TCPC = new tcpclient (textbox1.text,
Int32.parse (textbox3.text ));
// Submit a connection request to the remote computer
Tcpstream = TCPC. getstream ();
// If the connection request is established, the data stream used for data transmission is obtained.
Statusbar1.panels [0]. Text = "successfully connected to a remote computer! ";
Button2.enabled = true;
Button1.enabled = false;
Button4.enabled = true;
}
Catch (exception)
{
Statusbar1.panels [0]. Text = "the target computer rejects the connection request! ";
}
}
8. Add the following code after the main function in form1.cs. The following Code defines a process named "listen:
Private void listen ()
{
Try
{
Tllisten1 = new tcplistener (int32.parse (textbox2.text ));
Tllisten1.start ();
// Specifies the port number for listening.
Statusbar1.panels [1]. Text = "listening ...";
// Receive connection requests from remote computers and obtain the socket instance used to receive data
Sksocket = tllisten1.acceptsocket ();
// Obtain the network remote endpoint corresponding to the remote computer
Endpoint tempremoteep = sksocket. remoteendpoint;
Ipendpoint tempremoteip = (ipendpoint) tempremoteep;
Iphostentry host = DNS. gethostbyaddress
(Tempremoteip. Address );
String hostname = host. hostname;
// Obtain the name of the remote computer based on the network remote endpoint corresponding to the obtained Remote Computer
Statusbar1.panels [1]. Text = "'" + hostname + "'" +
"The remote computer is correctly connected! ";
// Loop listening
While (listenerrun)
{
Byte [] stream = new byte [80];
// Define the data buffer zone for receiving data from a remote computer
String time = datetime. Now. tostring ();
// Obtain the current time
Int I = sksocket. receivefrom (stream,
Ref tempremoteep );
// Receives data and stores it in the defined buffer zone.
String smessage = system. Text. encoding. utf8.
Getstring (Stream );
// Parse the content from the buffer with the specified Encoding
Listbox2.items. Add (Time + "" + hostname + ":");
Listbox2.items. Add (smessage );
// Display the received data
}
}
Catch (system. Security. securityexception)
{
MessageBox. Show ("firewall security error! "," Error ",
Messageboxbuttons. OK, messageboxicon. Exclamation );
}
}
9. Use the following code to replace the processing code corresponding to the Click Event of the button2 component in form1.cs. The following code is used to disconnect the current connection:
Private void button2_click (Object sender, system. eventargs E)
{
Listenerrun = false;
TCPC. Close ();
Statusbar1.panels [0]. Text = "disconnected! ";
Button1.enabled = true;
Button2.enabled = false;
Button4.enabled = false;
}
10. use the following code to replace the processing code corresponding to the Click Event of the button3 component in form1.cs. The following code initializes the thread instance and starts the thread Based on the listen process defined above, achieve the purpose of listening port:
Private void button3_click (Object sender, system. eventargs E)
{
Th = new thread (New threadstart (Listen ));
// Initialize the thread instance in the listen Process
Th. Start ();
// Start this thread
}
11. Use the following code to replace the processing code corresponding to the Click Event of the button4 component in form1.cs. The following code is used to send information to the specified port number of the remote computer.
Private void button4_click (Object sender, system. eventargs E)
{
Try
{
String smsg = textbox4.text;
String myname = DNS. gethostname ();
// Write data to the data stream with a specific encoding,
// The default instance is utf8encoding.
Reqstreamw = new streamwriter (tcpstream );
// Write the string to the data stream
Reqstreamw. Write (smsg );
// Clear all the buffers of the current writer and write all the buffered data to the basic stream.
Reqstreamw. Flush ();
String time = datetime. Now. tostring ();
// Display the transmitted data and time
Listbox1.items. Add (Time + "" + myname + ":");
Listbox1.items. Add (smsg );
Textbox4.clear ();
}
// Exception Handling
Catch (exception)
{
Statusbar1.panels [0]. Text = "unable to send information to the target computer! ";
}
}
12. Replace the processing code corresponding to the "dispose" Process in form1.cs with the following code. The following code is used to clear resources that are not recycled after the program exits:
Protected override void dispose (bool disposing)
{
Try
{
Listenerrun = false;
Th. Abort ();
Th = NULL;
Tllisten1.stop ();
Sksocket. Close ();
TCPC. Close ();
}
Catch {}
If (disposing)
{
If (components! = NULL)
{
Components. Dispose ();
}
}
Base. Dispose (disposing );
}
13. Run the program to achieve point-to-point network communication:
Click the shortcut key F5 to compile the program and distribute it to two computers on the network. After correctly entering the listening port number, remote computer IP address, and remote port number, click listener port and connect to remote computer to establish a chat connection. You can use the send message button to chat. Figure 2 shows the runtime interface for communication.
Figure 2 run Interface
V. Summary:
Network point-to-point communication programs are not divided into client programs and server programs as client/server model programs. It is a combination of client programs and server programs, so it is relatively troublesome in the specific program design. The preceding example of using Visual C # To implement point-to-point network communication is not complex, but involves a wide range of knowledge. For example, many network functions, such as listening port numbers, establishing connections, sending data, and receiving data, are involved in thread processing and Resource Recycling. Understanding and understanding how to deal with these problems is necessary to compile more complex network applications.