socket programming 15: how to keep the server listening to the client's requests?

Posted by smacpettit on Mon, 11 Nov 2019 19:48:26 +0100

The previous program, no matter the server or the client, has a problem, that is, it exits immediately after processing a request, which is not of great practical significance. Can you always accept requests from clients like a Web server? Yes, just use the while loop.

Modify the echo program so that the server can continuously respond to the client's request.

server.cpp:

#include <stdio.h>
#include <winsock2.h>
#Pragma comment (LIB, "WS2? 32. Lib") / / load WS2? 32.dll

#define BUF_SIZE 100

int main(){
WSADATA wsaData;
WSAStartup( MAKEWORD(2, 2), &wsaData);

//Create socket
SOCKET servSock = socket(AF_INET, SOCK_STREAM, 0);

//Bind socket
sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr)); //Each byte is filled with 0
sockAddr.sin_family = PF_INET; //Use IPv4 address
sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //Specific IP address
sockAddr.sin_port = htons(1234); //port
bind(servSock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));

//Enter monitoring state
listen(servSock, 20);

//Receive client requests
SOCKADDR clntAddr;
int nSize = sizeof(SOCKADDR);
char buffer[BUF_SIZE] = {0}; //Buffer
while(1){
SOCKET clntSock = accept(servSock, (SOCKADDR*)&clntAddr, &nSize);
int strLen = recv(clntSock, buffer, BUF_SIZE, 0); //Receive data from client
send(clntSock, buffer, strLen, 0); //Return data as is

closesocket(clntSock); //Close socket
memset(buffer, 0, BUF_SIZE); //Reset buffer
}

//Close socket
closesocket(servSock);

//Terminating the use of DLL s
WSACleanup();

return 0;
}


client.cpp:

#include <stdio.h>
#include <WinSock2.h>
#include <windows.h>
#Pragma comment (LIB, "WS2? 32. Lib") / / load WS2? 32.dll

#define BUF_SIZE 100

int main(){
//Initialize DLL
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);

//Request to server
sockaddr_in sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr)); //Each byte is filled with 0
sockAddr.sin_family = PF_INET;
sockAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
sockAddr.sin_port = htons(1234);

char bufSend[BUF_SIZE] = {0};
char bufRecv[BUF_SIZE] = {0};

while(1){
//Create socket
SOCKET sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
connect(sock, (SOCKADDR*)&sockAddr, sizeof(SOCKADDR));
//Get the string entered by the user and send it to the server
printf("Input a string: ");
gets(bufSend);
send(sock, bufSend, strlen(bufSend), 0);
//Receive data from server
recv(sock, bufRecv, BUF_SIZE, 0);
//Output received data
printf("Message form server: %s\n", bufRecv);

memset(bufSend, 0, BUF_SIZE); //Reset buffer
memset(bufRecv, 0, BUF_SIZE); //Reset buffer
closesocket(sock); //Close socket
}

WSACleanup(); //Stop using DLL
return 0;
}

Run the server first, and then the client. The results are as follows:
Input a string: c language
Message form server: c language
Input a string: C language Chinese net
Message form server: C language Chinese network
Input a string: learn C/ C++ A good website for programming
Message form server: a good website for learning C/C + + Programming

while(1) lets the code go into a loop. Unless the user closes the program, the server will listen to the client's request all the time. The same is true for the client, which continuously initiates a connection to the server.

It should be noted that calling closesocket() in server.cpp not only closes the socket on the server side, but also notifies the client that the connection has been disconnected, and the client will also clean up Socket related resources, so client.cpp needs to place socket (while) inside the while loop, because every time the request is completed, it will clean socket, and the next request will need to be re created. We will explain it in detail later.

Topics: socket C Programming Web Server