Я новичок в программировании сокетов на C ++ и UNIX. Я работаю на простой серверной и клиентской программе. Клиентская программа считывает данные из файла .txt, который содержит хост и количество пингов для отправки. Клиент отправляет строку на сервер, где сервер анализирует строку и запускает команду ping. Затем сервер отправляет вывод обратно клиенту. Проблема у меня в том, что сервер отправляет только 2 строки вывода ping, а не все. Я не уверен, если это проблема в моем коде сервера или кода клиента.
Код сервера:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <string>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <sysexits.h>
using namespace std;
#define MAXLINE 2048 /*max text line length*/
#define LISTENQ 8 /*maximum number of client connections */
int main (int argc, char **argv)
{
int listenfd, connfd, n;
socklen_t clilen;
char buf[MAXLINE];
struct sockaddr_in cliaddr, servaddr;
int portNumber = atoi(argv[1]);
char *ch;
char hostName[50];
char pingsToSend[50];
char *pingArgArray[5];
pid_t cpid;
int status;
int i;
//creation of the socket
listenfd = socket (AF_INET, SOCK_STREAM, 0);
//preparation of the socket address
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(portNumber);
bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
listen(listenfd, LISTENQ);
printf("%s%d\n","Server - Start with Port=",portNumber);
printf("%s%d\n","\tThe server PID is:",getpid());
for ( ; ; ) {
clilen = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *) &cliaddr, &clilen);
while ( (n = recv(connfd, buf, MAXLINE,0)) > 0) {
printf("\n%s","Server - Input Data received: ");
puts(buf);
//Parse each line of input file
ch = strtok(buf, " ");
strcpy(hostName,ch);
ch = strtok(NULL, " ");
strcpy(pingsToSend,ch);
//Get rid of deprecated conversion from string constant to 'char*' error
string binCommand = "/bin/ping";
string dashC = "-c";
char * arrayBinCommand = new char [binCommand.length()+1];
strcpy(arrayBinCommand,binCommand.c_str());
char * arrayDashC = new char [binCommand.length()+1];
strcpy(arrayDashC,dashC.c_str());
//Array of arguments to pass to execv
pingArgArray[0] = arrayBinCommand;
pingArgArray[1] = hostName;
pingArgArray[2] = arrayDashC;
pingArgArray[3] = pingsToSend;
pingArgArray[4] = NULL;
if (cpid == 0){
fprintf(stdout,"Server - Fork child process");
fprintf(stdout,"\nServer - Sent results of the ping comand to the client via socket");
close(listenfd);
dup2(connfd,STDOUT_FILENO);
dup2(connfd,STDERR_FILENO);
close(connfd);
execvp(pingArgArray[0],pingArgArray);
}
}
if (n < 0) {
perror("Read error");
exit(1);
}
}
//close listening socket
close(listenfd);
}
Код клиента:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <unistd.h>
#include <sys/wait.h>
using namespace std;
#define MAXLINE 2048 /*max text line length*/
int main(int argc, char **argv)
{
int sockfd;
struct sockaddr_in servaddr;
char sendline[MAXLINE], recvline[MAXLINE];
int portNumber = atoi(argv[2]);
int serverIp = atoi(argv[1]);
string line;
ifstream pingArgumentsIn("pingData.txt");
//basic check of the arguments
if (argc !=3) {
perror("Usage: TCPClient <IP address of the server> <port # of the server>");
exit(1);
}
printf("%s%d%s%d\n","Client - Start with IP=",serverIp," and Port=",portNumber);
printf("%s%d\n","\tThe client PID is:",getpid());
//Catch error if file is not found or cant be opened
if (!pingArgumentsIn){
cout << "File could not be opened\n";
return 0;
}
//Create a socket for the client
//If sockfd<0 there was an error in the creation of the socket
if ((sockfd = socket (AF_INET, SOCK_STREAM, 0)) <0) {
perror("Client - Problem in creating the socket");
exit(2);
}
//Creation of the socket
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr= inet_addr(argv[1]);
servaddr.sin_port = htons(portNumber); //convert to big-endian order
//Connection of the client to the socket
if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr))<0) {
perror("Client - Problem in connecting to the server");
exit(3);
} else {
printf("\n%s", "Client - Connected to server");
}
while (getline(pingArgumentsIn,line)){
printf("\n%s%s","Client - Input data is: ",line.c_str());
printf("\n%s", "Client - Sending input data to the server");
send(sockfd, line.c_str(), strlen(line.c_str()), 0);
if (recv(sockfd, recvline, MAXLINE,0) == 0){
//error: server terminated prematurely
perror("Client - The server terminated prematurely");
exit(4);
}
printf("\n%s", "Client - Received output from the server via socket: ");
printf("\n");
fputs(recvline, stdout);
}
exit(0);
}
Здесь показан текущий вывод Я получаю:
Client - Received output from the server via socket:
PING www.google.com (172.217.12.68) 56(84) bytes of data.
64 bytes from dfw28s05-in-f4.1e100.net (172.217.12.68): icmp_seq=1 ttl=48 time=1.92 ms
Когда это то, что я ожидаю:
Client - Received output from the server via socket:
PING www.google.com (172.217.12.68) 56(84) bytes of data.
64 bytes from dfw28s05-in-f4.1e100.net (172.217.12.68): icmp_seq=1 ttl=48 time=1.96 ms
64 bytes from dfw28s05-in-f4.1e100.net (172.217.12.68): icmp_seq=2 ttl=48 time=1.99 ms
64 bytes from dfw28s05-in-f4.1e100.net (172.217.12.68): icmp_seq=3 ttl=48 time=1.91 ms
64 bytes from dfw28s05-in-f4.1e100.net (172.217.12.68): icmp_seq=4 ttl=48 time=1.96 ms
64 bytes from dfw28s05-in-f4.1e100.net (172.217.12.68): icmp_seq=5 ttl=48 time=1.96 ms
--- www.google.com ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4004ms
rtt min/avg/max/mdev = 1.915/1.959/1.992/0.054 ms