After several days of study, I finally solved the synchronization communication program between the client and the server developed by using the socket send and receive methods in the C # network programming; the interface program that allows the client to send messages to the server. the main method is:
1. Socket socket programming knowledge, using IPaddress to define an IP address, ipendpoint to define a host, socket instance socket object sock and thread member variables;
2. Call the bind method to bind the port, listen listening port, accept to accept the connection request, and connect to connect the client and server;
3. After the connection is established, the send and receive methods are used to receive messages sent in connection requests cyclically through the thread to implement communication and display them in the corresponding control;
4. Call the close and shutdown methods of the socket to close the socket and stop the connection listening.
The following is the result after the program runs:
(The Server accepts the message sent by the client: this is a unilateral communication, but the methods are the same for both parties, because the "enjoy using this server" of the server is also displayed on the client)
(Client)
The source code of this program is as follows:
Server
Using system; using system. collections. generic; using system. componentmodel; using system. data; using system. drawing; using system. LINQ; using system. text; using system. threading. tasks; using system. windows. forms; // Add a new namespace using system. net; using system. net. sockets; using system. threading; namespace tbserver {public partial class form1: FORM {public form1 () {initializecomponent () ;}// add private member private ipaddr ESS myip = IPaddress. parse ("127.0.0.1"); // defines the IP object private ipendpoint myserver; // defines the host private socket sock; // socket object instance private bool Sign = true; // control loop private thread; // create control thread private socket socklin; // temporary socket, accept client connection requests // double-click "Start listening" button to add the Click Event private void button#click (Object sender, eventargs e) {try {myip = IPaddress. parse (textbox1.text); // string to IP} catch {MessageBox. show ("the IP address format you entered is incorrect! ");} Try {// define host myserver = new ipendpoint (myip, int32.parse (textbox2.text); // construct socket sock = new socket (addressfamily. interNetwork, sockettype. stream, protocoltype. TCP); // bind the port sock. BIND (myserver); // start listening to sock. listen (10); // Add textbox3 to the status bar to replace statusstrip1 (not used) textbox3.text = "host" + textbox1.text + "Port" + textbox2.text + "Start listening "; // construct thread = new thread (New threadstart (targett); // targett custom function Accept client connection requests // start the thread to accept connections and receive data threads. start ();} catch (exception MSG) {textbox3.text = MSG. message ;}// targett (): custom function. This method starts to receive the client connection request private void targett () {socklin = sock. accept (); // accept the connection request Sign = true; // loop flag variable true // Connect if (socklin. connected) {textbox3.text = "connect to client"; // information is fed back to client byte [] bytenum = new byte [64]; // The bytenum = system is constructed. text. encoding. bigendianunicode. getbytes ("enjoy drinking This server ". tochararray (); socklin. send (bytenum, bytenum. length, 0); // send data // The sign is true. The loop accepts data while (sign) {byte [] bytenum2 = new byte [128]; socklin. receive (bytenum2, bytenum2.length, 0); // accept data string STR = system. text. encoding. bigendianunicode. getstring (bytenum2); richtextbox1.appendtext (STR + "\ r \ n"); // display string // obtain the number of rows of richtextbox1 int length = richtextbox1.lines. length; // If the string from the second to the last line sent by the client is "@", disconnect if (RIC Htextbox1.lines [length-2] = "@") {textbox3.text = "disconnect from the client"; // close the socket instance (both indicates that the sending and receiving are closed) socklin. shutdown (system. net. sockets. socketshutdown. both); socklin. close (); Sign = false; // set it to false to exit the loop }}// double-click "Stop listening" to add the Click Event private void button2_click (Object sender, eventargs E) {try {Sign = false; sock. close (); textbox3.text = "host" + textbox1.text + "Port" + textbox2.text + "listener stop";} catch {message Box. Show ("the listener has not started yet. disabling it is invalid! ") ;}} // When loading form, it is set to unsafe access to prevent invalid thread operation private void form1_load (Object sender, eventargs e) {// non-secure thread access, do not check whether the thread is secure. checkforillegalcrossthreadcils = false ;}}}
Client
Using system; using system. collections. generic; using system. componentmodel; using system. data; using system. drawing; using system. LINQ; using system. text; using system. threading. tasks; using system. windows. forms; // Add a new namespace using system. net; using system. net. sockets; using system. threading; namespace tbclient {public partial class form1: FORM {public form1 () {initializecomponent () ;}// add private member private ipaddr ESS myip = IPaddress. parse ("127.0.0.1"); // defines the IP object private ipendpoint myserver; // defines the host private socket sock; // specifies the private thread of the socket object instance; // create a control thread // double-click "request connection" to add the Click Event private void button#click (Object sender, eventargs e) {try {myip = IPaddress. parse (textbox1.text); // string to IP} catch {MessageBox. show ("the IP address format you entered is incorrect! ");} Try {// construct the host myserver = new ipendpoint (myip, int32.parse (textbox2.text); // construct the socket sock = new socket (addressfamily. interNetwork, sockettype. stream, protocoltype. TCP); // request to connect to sock. connect (myserver); // construct thread = new thread (New threadstart (targett); // targett custom function: accept client connection requests // start the thread to accept connections and receive data threads. start (); // Output Message textbox4.text = "with host" + textbox1.text + "Port" + textbox2.text + "connection successful";} Cat CH (exception MSG) {MessageBox. show (MSG. message) ;}}// targett (): custom function. This method starts to receive the client connection request private void targett () in a loop () {// construct byte array byte [] bytenum = new byte [64]; // accept data sock. receive (bytenum, bytenum. length, 0); // converts a character array to a string STR = system. text. encoding. bigendianunicode. getstring (bytenum); textbox3.text = STR;} // double-click "Send message" to add the Click Event private void button2_click (Object sender, eventargs e) {// construct a byte array Byte [] bytenum = new byte [64]; // send content string send = richtextbox1.text + "\ r \ n"; // convert string to bytenum = system. text. encoding. bigendianunicode. getbytes (send. tochararray (); // send data sock. send (bytenum, bytenum. length, 0); // construct the thread threadsend = new thread (New threadstart (targett); // start the thread to accept the data threadsend. start () ;}// double-click "close connection" to add the Click Event private void button3_click (Object sender, eventargs e) {byte [] Bytenum = new byte [64]; string send = "@" + "\ r \ n"; bytenum = system. text. encoding. bigendianunicode. getbytes (send. tochararray (); sock. send (bytenum, bytenum. length, 0); // send "@" to the server try {sock. close (); textbox4.text = "host" + textbox1.text + "Port" + textbox2.text + "Disconnect";} catch {MessageBox. show ("the connection has not been established, and the disconnection is invalid! ") ;}} // When loading form, it is set to unsafe access to prevent invalid thread operation private void form1_load (Object sender, eventargs e) {// non-secure thread access, do not check whether the thread is secure. checkforillegalcrossthreadcils = false ;}}}
The main problems and solutions I encountered in this program are as follows:
1. The program is always stuck in the initial stage. Why is there no response?
Because the socket accept () function is in blocking mode, its execution will cause program blocking and should be placed in the thread for execution; otherwise, the current thread will be blocked, when a message is not returned in the stuck state, the subsequent code will not be executed. Therefore, you need to put accept in the created thread and put it in the socklin = sock in the targett () function. accept;
2. Why does sock and socklin (temporarily accept client connection requests) confuse in the defined socket object instance?
Socklin = sock. Accept, which is the connection request sent by the client. Therefore, if (socklin. Connected) is used to determine the connection, and send and accept data using the send and receive methods of socklin;
3. There is always an error "invalid inter-thread operation: Never access it by the thread that created the control?
The Windows form control is not thread-safe. If several threads operate on the status of a control, the control may be in different states, with contention or deadlock. my solution is to add the load event for form loading. During load, set the value of the checkforillegalcrossthreadcils attribute to false. in this way, when a non-secure thread is accessed, the runtime environment does not check whether it is thread-safe. this is from with the blog, For details see: http://blog.csdn.net/wangchao0605/article/details/5010864
Summary:
Finally, after a week of study and materials reading, I got the program out and learned a lot. I also thanked the above bloggers and some books. I hope this article will be useful to you. Sorry for any mistakes or shortcomings!
(By: eastmount 2013-7-22)