Multi-thread communication-TCP chat program-VC ++

Source: Internet
Author: User
Tags htons
Operating System Course Design-multi-thread communication-TCP chat program-VC ++

Operating SystemCourse Design task book

I,Design question: multi-machine process Communication

The socket process communication technology is used to compile chat room programs to implement server-based Concurrent multi-host information forwarding. If each client is online, it can chat and send receiving files in real time. If a client is offline, the messages sent to it can be cached by the server, after the connection is reconnected, You can automatically receive information or files forwarded by the server. The cache and forwarding control algorithms can refer to the related theories in the operating system course, such as producer and consumer Process Synchronization Methods and buffer pool technology.
Ii. Detailed description of design ideas and functions
The TCP protocol is used, so it belongs to the Client/Server mode. Therefore, two programs, namely the chat server and the chat client, are required to implement the following functions: any computer with a client program can connect to the server through the IP address of the server, and then enter the chat room to chat with other customers connected to the server. When the customer's chat ends, you can disconnect from the server to release the process and allow other waiting customers to enter the chat room. This chat room supports connections between up to 50 clients at the same time, if the server configuration is high, you can modify the program to increase the number of simultaneous connections.
Iii. methods, technologies, operating environment and Configuration
This chat program adopts the TCP protocol and is written in VC ++. It belongs to the Client/Server mode. Multithreading mechanism is adopted. Windows Sockets is used to implement communication between multiple computers (multiple processes). socket actually provides a communication port in the computer, you can use this port to communicate with any computer with a socket interface. Applications are transmitted over the network and the received information is implemented through this socket interface. In Client/Server mode, customer applications request services from server programs. A service program listens to service requests at a well-known address, that is, the service process remains dormant until a customer initiates a connection request to the service address. At this moment, the service program is "awakened" and the appropriate response to the customer's request is provided to the customer. This chat program is implemented based on this idea. The program is divided into two parts: TCP chat server and TCP chat client. Both have their own socket interfaces, in which the server-side socket interface needs to be bound to a fixed address (Implementation statement: ock = socket (af_inet, sock_stream, 0 );), wait for the client connection (Implementation statement: Listen (sock, 5 );). The process of waiting for client connection is implemented through the multi-process mechanism.
The chat program is compiled and implemented on Visual C ++ 6.0. The test runs successfully on Windows and XP.
There are no special requirements on the client's computer configuration. Because the maximum connection process set is 50, the server requirements are not high.
4. Key source programs and their detailed comments
<I>, Server:
1, SocketInitialization
// Initialization dialog box
Bool ccsocketdlg: oninitdialog ()
{

Count = 0;

M_list.insertcolumn (0, "message ");

M_list.setcolumnwidth (0,435 );

M_edit.setlimittext (99 );

For (INT I = 0; I <50; I ++) // initialize the socket Array

Msgsock= NULL;

Serv. sin_addr.s_addr = htonl (inaddr_any); // set the address

Serv. sin_family = af_inet;

Serv. sin_port = 5000; // htons (5000 );

Addlen = sizeof (SERV );

M_button.enablewindow (false );

Sock = socket (af_inet, sock_stream, 0); // create a socket

If (BIND (sock, (sockaddr *) & serv, addlen) // bind

{

M_edit.setwindowtext ("binding error ");

} Else

{

M_edit.setwindowtext ("server created successfully"); // a prompt is displayed, indicating that the server is created successfully.

Listen (sock, 5); // start listening

Afxbeginthread (& Thread, 0); // call thread

}

Return true;

}
2Receiving thread
//Server thread
Uint thread (lpvoid P)
{

Char buff [100]; // defines the buffer

Csize size;

Size. Cx = 0;

Size. Cy = 30;

Int S = 1, msgcount, loop = 1, flag = 0;
Ccsocketdlg * DLG = (ccsocketdlg *) afxgetapp ()-> getmainwnd (); // obtain the handle of the current running dialog box

Msgcount = DLG-> getcount (); // obtain the serial number of the unused Array

If (msgcount =-1) // if it is not equal to-1, there is a vacant socket

Loop = 0;

If (loop)

{

S = 1;

DLG-> msgsock [msgcount] = accept (DLG-> sock, (sockaddr *) & (DLG-> SERV), & (DLG-> addlen ));//
Wait for the customer to connect with the vacant socket

If (DLG-> msgsock [msgcount] = invalid_socket)

{

DLG-> m_edit.setwindowtext ("error accept"); // if an error is returned, an error is returned.

}

Else

{

Afxbeginthread (thread, 0); // If the connection is successful with the client, start a thread again

DLG-> setforegroundwindow (); // displays the successful connection information.

DLG-> m_list.insertitem (DLG-> count ++, "connection successful ");

DLG-> m_list.insertitem (DLG-> count ++, inet_ntoa (DLG-> Serv. sin_addr ));

DLG-> m_list.scroll (size );

DLG-> m_button.enablewindow (true );

While (s! = Socket_error) // if no error occurs, it will wait until the data arrives.

{

S = Recv (DLG-> msgsock [msgcount], buff,); // receives data cyclically.

DLG-> setforegroundwindow ();

If (s! = Socket_error) if the receiving is successful, the received data is displayed.

{

DLG-> m_list.insertitem (DLG-> count ++, buff );

DLG-> m_list.scroll (size );

DLG-> sendtoall (DLG-> msgsock [msgcount], buff); // send information to all clients

}

}

Send (DLG-> msgsock [msgcount], "disconnected",); // if an error occurs, send the connection interruption message to the client.

DLG-> m_list.insertitem (DLG-> count ++, "disconnected"); // display related information

DLG-> m_list.scroll (size );

DLG-> msgsock [msgcount] = NULL; // set this socket to null

For (INT I = 0; I <50; I ++) // determines if other customers are still connected.

If (DLG-> msgsock! = NULL)

Flag = 1;

If (flag! = 1) // if no client connection is available, set the send button to unavailable.

DLG-> m_button.enablewindow (false );

Closesocket (DLG-> msgsock [msgcount]); // close the connection

}

}

Afxendthread (0); // terminate the thread

Return 0;
}
3, Data Transmission
When you enter the information to be sent in the text box, and then click "send", the following code is executed.
// Send data
Void ccsocketdlg: onbutton1 ()
{

Char buff [100];

M_edit.getwindowtext (buff, 99); // obtain information in the current text box

M_edit.setwindowtext (""); // clear text box information

M_list.insertitem (count ++, buff); // Insert the data to be sent to the list box.

Csize size;

Size. Cx = 0;

Size. Cy = 30;

M_list.scroll (size );

For (INT I = 0; I <50; I ++) // send messages to all customers cyclically

{

If (msgsock! = NULL)

Send (msgsock, Buff, 100,0 );

}
}
<II>Client
1,
Connect to the server
The programs connecting to the server are handled in the "connection" button-clicked event.
// Connect to the server and handle the event by pressing the button
Void ccsocketclidlg: onbutton2 ()
{

Char IPaddress [35]; // defines the scalar to save the server address

M_edit2.getwindowtext (IPaddress, 30); // obtain the server address

CLI. sin_addr.s_addr = inet_addr (IPaddress); // set the address to be connected to the socket.

CLI. sin_family = af_inet;

CLI. sin_port = 5000; // htons (5000); // set the server port

Clisock = socket (af_inet, sock_stream, 0 );
// Create a socket

EE = 1;

Afxbeginthread (thread, 0); // start the thread
}
2,
Receiving data thread
After you click the "Connect" button, the Program sets the connection and calls "afxbeginthread (thread, 0 );This thread is started.
Uint thread (lpvoid V)
{

Char buff [100];

Char array [25] [30] = // defines an array to store some IP addresses

{"192.168.0.3 ",

... (Some IP addresses are omitted here)

"192.168.0.30 "};

Csize size;

Size. Cx = 0;

Size. Cy = 30;

Int S = 1, addcount = 0;

Ccsocketclidlg * DLG = (ccsocketclidlg *) afxgetapp ()-> getmainwnd (); // obtain the dialog box

DLG-> m_connect.enablewindow (false );

DLG-> m_disconnect.enablewindow (true );

While (connect (DLG-> clisock, (sockaddr *) & (DLG-> cli), sizeof (DLG-> cli) & DLG-> Ee! = 0) // connect to the server

{

DLG-> m_edit.setwindowtext ("Wait .....");

For (INT I = 0; I <= 65000; I ++) // empty Loop

For (Int J = 0; j <= 200; j ++ );

If (addcount = 25)

Addcount = 0;

DLG-> cli. sin_addr.s_addr = inet_addr (array [addcount ++]); // if the connection fails, connect to the next address

}

If (DLG-> EE = 1) // If the connection is successful, the related information is displayed.

DLG-> m_list.insertitem (DLG-> count ++, "connection successful ");

DLG-> m_button1.enablewindow (true); // set the sending button to available.

DLG-> setforegroundwindow ();

While (s! = Socket_error & DLG-> Ee! = 0) // obtain data cyclically

{

S = Recv (DLG-> clisock, buff, 0); // call the Recv function to receive data

DLG-> setforegroundwindow ();

If (s! = Socket_error & DLG-> Ee! = 0) // if no error occurs and the connection is not closed, the received data is displayed.

DLG-> m_list.insertitem (DLG-> count ++, buff );

DLG-> m_list.scroll (size );

}

Send (DLG-> clisock, "disconnected",); // if an error occurs, send the disconnect command

DLG-> m_button1.enablewindow (false); // you can specify the properties of a widget.

DLG-> m_connect.enablewindow (true );

DLG-> m_disconnect.enablewindow (false );

Closesocket (DLG-> clisock); // close the socket

Afxendthread (0); // terminate the thread

Return 0;
}
3,
Data Transmission
Data transmission means that the client sends information to the server and other clients, and sends the information to other users through the server. Therefore, the customer only needs to send the message to the server.
// The user clicks send button to send information
Void ccsocketclidlg: onbutton1 ()
{

Char buff [100];

Csize size;

Size. Cx = 0;

Size. Cy = 30;

M_edit.getwindowtext (buff, 99); // get the sending information

M_edit.setwindowtext ("");

M_list.insertitem (count ++, buff );

M_list.scroll (size );

Send (clisock, buff,); // send data
}
5. execution results and analysis.
1Enable the server chat program.

 

Attachment: you cannot download or view attachments in your user group.

Figure 1: Create a server (Prompt: the server is successfully created)

The server is successfully created and automatically bound to the IP address of the server. Wait for the client connection request. the send button is unavailable at this time. When a client is connected, the send button becomes available. Enter the information in the edit box below to send the message.

 

Attachment: you cannot download or view attachments in your user group.

Figure 2: a client is successfully connected (the IP address is the server address)

 

Attachment: you cannot download or view attachments in your user group.

Figure 3: the server sends "hello" and accepts "client reply"

 

Attachment: you cannot download or view attachments in your user group.

Figure 4: a client is disconnected (Prompt: disconnected)

2. The client is running.
Enter the IP address of the server in the client program, and click Connect. If the connection is successful, a message indicating successful connection is displayed. Then, enter the information in the edit box below to send the message. If the connection fails, a message is displayed, indicating that the server IP address is entered incorrectly or that the server reaches the maximum process. The client program can pre-set the IP addresses of a batch of servers in the program source code, and then click Connect. If the currently displayed server cannot be connected successfully, the program automatically connects to the pre-configured second IP address, test the connection continuously. When the connection is successful with a server, the system prompts that the connection is successful and stops the loop.

 

Attachment: you cannot download or view attachments in your user group.

Figure 5: running the client (the server address displays the preset IP address)

 

Attachment: you cannot download or view attachments in your user group.

Figure 6: Client Connection successful

Attachment: you cannot download or view attachments in your user group.

 

Figure 7: "Hello!" sent by the client !" And accept the "server-side reply" message.

6. Experiences
After this course design, I have basically mastered the application of WinSock programming and have a certain understanding of Calling Windows API functions. In the face of the various popular chat rooms on the internet, I have a certain understanding, it is no longer so mysterious. In addition, I understand the server-based Concurrent multi-host information forwarding technology. In the chat room program, this is implemented as follows: when a client sends a message to another client, it does not send it directly, but first sends it to the server, the server then delivers the information to all other clients connected to the server. In addition, I learned more about VC ++ and learned more about its powerful functions. Finally, the most important thing is to apply the theoretical knowledge learned in the operating system course to practice and have a deeper understanding of it.
VII. Main references:
1. Computer Operating System tutorial;
2. Visual C ++ network communication protocol analysis and application implementation (edited by Wang Xiaoping Zhong Jun;
3. msdn reference.
Go to: http://www.youzaiyouzai.cn/showtopic.aspx? Forumid = 56 & topicid = 1570 & go = next

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.