I got a problem on Linux socket programming, and I can`t understand the situation.
It's a simple echo server-client program pair.
This is what I programmed:
This is the echoClient.
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#define RCV_BUF_SIZE 512    //receive buffer size
int main(int argc, char *argv[])
{
    int sock;   //socket
    struct sockaddr_in echoServAddr;//server socket address struct
    unsigned short echoServPort;    //server port
    char *servIP;   //server address
    char *echoString;   //sending msg
    char echoBuffer[RCV_BUF_SIZE];  //receive buffer
    unsigned int echoStringLen = 0; //msg length
    int bytesRcvd, totalBytesRcvd; //received bytes, total bytes received
    if((argc < 2) || (argc > 3)) //if there are no right arguements, throw error and exit program
    {
        printf("Usage : %s <Server IP> [<Echo Port>]\n", argv[0]);
        exit(1);
    }
    servIP = argv[1];
    if(argc == 3)//user defined exact port
    {
        echoServPort = atoi(argv[2]);
    }
    else//user didnt defined, use well-known port
    {
        echoServPort = 7;
    }
    if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)//if socket creation failed
    {
        printf("socket() failed\n");
        exit(1);
    }
    memset(&echoServAddr, 0, sizeof(echoServAddr));//memory reset
    echoServAddr.sin_family = AF_INET;  //setting server's address
    echoServAddr.sin_addr.s_addr = inet_addr(servIP);
    echoServAddr.sin_port = htons(echoServPort);
    if(connect(sock, (struct sockaddr*)&echoServAddr, sizeof(echoServAddr)) < 0)//connect try, -1 if failed
    {
        printf("connect() failed\n");
        perror("error is : ");
        exit(1);
    }
    printf("to exit, type \"/exit\"\n");
    while(1)
    {
        printf("insert echo word : ");
        echoString = gets();
        echoStringLen = strlen(echoString);
        if(echoStringLen > 512)//msg's length
        {
            printf("echo word is too long! (must be shorter than 512)\n");
            echoStringLen = 0;
            continue;
        }
        if(!strcmp(echoString, "\/exit"))
        {
            if(send(sock, echoString, echoStringLen, 0) != echoStringLen)//send to server, if sended bytes are smaller than string length
            {
                printf("sending close socket  failed\n");
                exit(1);
            }
            printf("clossing socket...\n");
            break;
        }
        if(send(sock, echoString, echoStringLen, 0) != echoStringLen)//send to server, if sended bytes are smaller than string length
        {
            printf("send() failed\n");
            exit(1);
        }
        totalBytesRcvd = 0;
        while(totalBytesRcvd < echoStringLen)//while received bytes are shorter than msg's length
        {
            if((bytesRcvd = recv(sock, echoBuffer, RCV_BUF_SIZE-1, 0)) <= 0)//-1 for null char
            {
                printf("recv() failed");
                exit(1);
            }
            totalBytesRcvd += bytesRcvd;    //++ total bytes received
            echoBuffer[bytesRcvd] = '\0';   //set last char to null cahr
            printf(echoBuffer); //print received buffer
        }
        printf("\n");
    }
    close(sock);
    exit(0);
}
and, this is the echoServer.
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <string.h>
#include <stdlib.h>
#define RCV_BUF_SIZE 512    //receive buffer size
#define MAX_BACKLOG 5
int main(int argc, char *argv[])
{
    struct sockaddr_in echoServAddr, echoClntAddr;  //define socket address(server, client)
    int servSock, clntSock; //socket 
    unsigned short echoServPort;    //port
    unsigned int clntLen;   //client address length
    char echoBuffer[RCV_BUF_SIZE];  //receive buffer
    int recvMsgSize;    //received msg size
    printf("echooo!\n\n");
    echoServPort = atoi(argv[1]);
    if((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) //socket creation failed
    {
        printf("socket() failed\n");
        exit(1);
    }
    if(argc != 2)   //if there are no right arguements, throw error and end program
    {
        printf("Usage : %s port\n", argv[0]);
        exit(1);
    }
    memset(&echoServAddr, 0, sizeof(echoServAddr));     //memory reset
    echoServAddr.sin_family = AF_INET;          //define server address type
    echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    echoServAddr.sin_port = htons(echoServPort);
    if(bind(servSock, (struct sockaddr *)&echoServAddr, sizeof(echoServAddr))<0)//bind try, return -1 if error
    {
        printf("bind() failed, socket number : %d\n", servSock);
        perror("Error : ");
        exit(1);
    }
    if(listen(servSock, MAX_BACKLOG) < 0)//listen try, return -1 if error
    {
        printf("listen(failed\n");
        exit(1);
    }
    while(1)
    {
        clntLen = sizeof(echoClntAddr);
        if((clntSock = accept(servSock, (struct sockaddr*)&echoClntAddr, &clntLen))<0)//accept try, return -1 if error
        {
            printf("recv() failed\n");
            exit(1);
        }
        while(1)
        {
            if((recvMsgSize = recv(clntSock, echoBuffer, RCV_BUF_SIZE, 0)) < 0)//recv try, return -1 if error
            {
                printf("recv() failed\n");
                exit(1);
            }
            if(!strcmp(echoBuffer, "\/exit"))
            {
                break;
            }
            if(send(clntSock, echoBuffer, recvMsgSize, 0) != recvMsgSize)//send try, if sended bytes are shorter than recved bytes: throw error
            {
                printf("send() failed\n");
                exit(1);
            }
        }
    }
    close(clntSock);
}
Here's the simple description.
- server starts and keep listening. 
- client connects. 
- client gets echo word from user, and send them to server. 
- server receives, and return them. 
- repeat, but once user enters "/exit", client sends "/exit", and closes socket. 
- and server receives "/exit", server closes socket and exits. 
But, here's the problem. The server is ok with sending echo word to client, but the server process 'sometimes' terminates without any sign when client sends "/exit". I don`t know why, but not always.
I tried to put perror() at end of the inner while loop, or outer while loop, but I can`t figure it out.
I would be very happy if someone help me out with this server problem.
 
    