Fourth, cross-system communication programming instances By an instance to specifically explain the application of Socket in UNIX and Windows cross-system communication programming.
A service called IRC (Internet Relay Chatting, Internet Online Chat System) is available on the Internet. The user can log in to the IRC server through the client program, you can talk to the customers who log in to the same IRC server, which is the usual chat room. Here, a program for implementing an IRC service on a network running a TCP / IP protocol is given. Among them, the server runs on Sco Open Server 5.0.5, and the client runs on Windows98 or Windows NT.
Run the server program on a computer, run the client program on the other computer of the same network, log in to the server, and you can chat between each customer.
Service
The server records the connected socket descriptor of each customer with a integer array named Client. All elements in this array are initialized to -1. At the same time, the server must handle the listener interface, but also handle all connected sockets, so I / O multiplexing needs to be used. The SELECT function core waits for any of the plurality of events, and wakes up only after one or more events or after a specified time. Maintain a read description set RSET, when there is a customer reaches, the first available entry (ie, the first entry of value -1) in the array client records the descriptive word of its connected interface. At the same time, add this connected description word to the read description rating RSET, the variable maxi is the maximum subscript of the currently used array client, and the variable maxFD 1 is the current value of the first parameter of the function Select. As shown below: (Suppose there are two customers and server establishment)
Figure 3 Second customer establishes a connected TCP server
Figure 4 The second customer establishes a connected data structure
The server listens on the specified port. Whenever a socket receives information, the received information will be sent to each client.
Its main source procedures are as follows: int Main (int Argc, char ** argv) {INT I, MAXI, MAXFD, Listenfd, Connfd, Sockfd; Int Nready, Client; SSIZE_T N; FD_SET RSET, ALLSET; char line [MaxLne]; socklen_t clilen; struct sockaddr_in cliaddr, servaddr; const int on = 1; listenfd = Socket (AF_INET, SOCK_STREAM, 0); if (setsockopt (listenfd, SOL_SOCKET, SO_REUSEADDR, & on, sizeof (on)) = - 1); err_ret ( "setsockopt error"); bzero (& servaddr, sizeof (servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl (INADDR_ANY); servaddr.sin_port = htons (SERV_PORT); Bind (listenfd, (SA *) & Servaddr, SearDR); Listen (Listenfd, Listenq); MAXFD = listenfd; // Initialization Maxi = -1; // Maximum subscript for (i = 0; i FD_SETSIZE; I ) IF (Client [i] <0 {client [i] = connfd; // Save the socket Break;} if (i = fd_setsize); Err_quit ("Too Many Clients"); fd_set (Connfd, & Allset ); // increase the socket to the read description word set IF (connfd> maxfd); MAXFD = connfd; if (i> maxi); MAXI = I; if (- NREADY <= 0) Continue;} for (i = 0; i <= maxi; i ) {// Check all users to connect IF ((sockfd = client [i]) <0) Continue; if (fd_isset (sockfd, & rset)) {IF (((n = readline , Line, Maxline) = 0) {// User Close Connection Close (SockFD); FD_CLR (SockFD, & Allset); Client [i] = - 1} else Printf ("% s", line); Broadcast (Client, Maxi, Line, N); if (--NReady <= 0) Break;}}}} // Send chat content to all connected users Broadcast (int Client, Int Maxi, Char * STR, SIZE_T N) { INT i; int suckfd; for (i = 0; i Register for some user-interested network events (such as receiving buffer full, allowing sending data, request connection, etc.). When these registered network events occur, the application's corresponding function will receive the message. The application must call the startup function wsastartup () before using the Windows Sockets DLL, and the function is two points: First, the application specifies the required Windows Sockets DLL version; the other is some technical details of the system Windows Sockets DLL. Each WSAStartup () function must correspond to a WSacleanup () function. When the application terminates, you must call your WSACLEANUP () to cancel yourself from OLL. The client program is designed under the Windows98 operating system with VC 6.0, and the program is generated by AppWizard, and the client core code is in the CTALKDIALOG class. Only one socket variable M_HSocket is connected to the server. After the connection is established, this Socket is sent and received information. Hand-added CTALKDIALOG: :: OnSockConnect (), complete the basic socket programming, apply for a socket for the client program, and bind the socket with the specified server, then send a connection request to the server, start the asynchronous selection function waiting for the server the response to. void CTalkDialog: "OnSockConnect () {struct sockaddr_in servaddr; WSADATA wsaData; if (WSAStartup (WINSOCK_VERSION, & wsaData)); {MessageBox (" Could not load Windows Sockets DLL, ", NULL, MB_Ok); return;} m_hSocket = socket ( AF_INET, SOCK_STREAM, 0); MEMSET (& ServadDR, 0, SIZEOF (SERVADDR)); servaddr.sin_family = AF_INET; // m_Iport, M_CSIP is the port number and IP address returned by the Registration dialog, servaddr.sin_port = htons (m_iport) Servaddr.sin_addr.s_un.s_addr = inet_addr (m_csip); if (Connect (m_hsocket, (sa *) & servaddr, sizeof (servaddr))! = 0) {AFXMessageBox ("Connection server failed!"); Getdlgitem (IDC_Button_out ) -> EnableWindow (FALSE); GetDlgItem (IDC_BUTTON_IN) -> EnableWindowTRUE GetDlgItem (IDC_EDIT-SEND) -> EnableWindow (FALSE); UpdateData (FALSE);} else {GetDlgItem (IDC_BUTTON_IN) -> EnableWindow (FALSE); GetDlgItem (IDC_BUTTON_OUT ) -> EnableWindow (TRUE); GetDlgItem (IDC_EDIT-SEND) -> EnableWindow (TRUE); int iErrorCode = WSAAsyncSelect (m_hSocket, m_hWnd, WM_SOCKET_READ, FD_READ); if (iErrorCode = SOCKET_ERROR) MessageB OX ("Wsaasyncselect Failed on Socket", NULL, MB_OK; }} Manually added CTalkDialog :: OnSockRead (), in response to a message sent by WinSock LRESULT CTalkDialog :: OnSockRead (WPARAM wParamLPARAM 1Param) {int iRead; int iBufferLength; int iEnd; int iSpaceRemain; char chIncomingData [100]; iBufferLength = iSpaceRemain = sizeof (chIncomingData); iEnd = 0; iSpaceRemain- = iEnd; iRead = recv (m_hSocket, (LPSTR) (chIncomingData iEnd), iSpaceRemain, 0); iEnd = iRead; if (iRead = SOCKET_ERROR) AfxMessageBox ( "reception data error!" ); chIncomingData [iEnd] = '/ 0'; if (lstrlen (chIncomingData) = 0) {m_csRecv = m_csRecv chIncomingData;! GetDlgItem (IDC_EDIT_RECV) -> SetWindowText ((LPCSTR) m_csRecv); CEdit * pEdit; pEdit = (CEdit * ) Getdlgitem; int i = pedit-> getLineCount (); pedit-> linescroll (i, 0);} return (ol);} Manually add CTALKDIALOG :: OnSend (), send data in the specified buffer Go out.