Linux系统基于TCP的回声(echo)服务器端/客户端(改写)

服务端是一个选代服务端,持续提供服务,同时只能为一个客户端提供服务。
信息传输协议(V2.0):1字节字符串长度+字符串内容(长度小于255)
信息传输协议(V3.0):4字节字符串长度+字符串内容(长度小于2^32)

服务器端:

#include 
#include 
#include 
#include 
#include 
#include 

#define BUF_SIZE 1024
void error_handling(char *message);


int main(int argc, char* argv[]){
    int serv_sock, clnt_sock;
    char message[BUF_SIZE];
    int i,len;

    struct sockaddr_in serv_adr, clnt_adr;
    socklen_t clnt_adr_sz;

    if(argc != 2){
        printf("Usage : %s \n", argv[0]);
        exit(1);
    }

    serv_sock = socket(PF_INET, SOCK_STREAM, 0);
    if(serv_sock == -1){
        error_handling("socket() error!");
    }

    memset(&serv_adr, 0, sizeof(serv_adr));
    serv_adr.sin_family = AF_INET;
    serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_adr.sin_port = htons(atoi(argv[1]));

    if(bind(serv_sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)) == -1){
        error_handling("bind() error!");
    }

    if(listen(serv_sock, 5) == -1){
    error_handling("listen() error!");
    }

    clnt_adr_sz = sizeof(clnt_adr);

    for(i = 0; i < 5; i++){
        clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_adr, &clnt_adr_sz);
        if(clnt_sock==-1)
            error_handling("accept() error!");
        else
            printf("Connected client %d\n", i + 1);

    while(1){
        len=0;
        read(clnt_sock,&len,1);

        read(clnt_sock,message,len);
        write(clnt_sock,message,len);
        }
        close(clnt_sock);
    }
    close(serv_sock);
    return 0;
}



void error_handling(char *message){
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

客户端:

#include 
#include 
#include 
#include 
#include 
#include 

#define BUF_SIZE 1024
void error_handling(char *message);

int main(int argc, char *argv[])
{
        int sock;
        char message[BUF_SIZE];
        char temp[BUF_SIZE];
        int str_len;
        int len;
        struct sockaddr_in serv_adr;

        if(argc != 3){
            printf("Usage: %s  ", argv[0]);
            exit(1);
        }

        sock = socket(PF_INET, SOCK_STREAM, 0);
        if(sock == -1)
            error_handling("socket() error!");

        memset(&serv_adr, 0, sizeof(serv_adr));
        serv_adr.sin_family = AF_INET;
        serv_adr.sin_addr.s_addr = inet_addr(argv[1]);
        serv_adr.sin_port = htons(atoi(argv[2]));

        if(connect(sock, (struct sockaddr*)&serv_adr, sizeof(serv_adr)) == -1)
            error_handling("connect() error!");
        else
            puts("Connected.........");

        while(1)
        {   printf("请输入字符串长度: ");
            scanf("%d",&len);
            write(sock,(char*)&len,1);

            printf("请输入内容(按Q退出): ");
            scanf("%s",temp);

            if(!strcmp(temp,"q")||!strcmp(temp,"Q"))
                break;

            write(sock,temp,len);

            read(sock,message,len);
            printf("消息为:%s\n",message);
        }
        close(sock);
        return 0;
}

void error_handling(char *message){
    fputs(message, stderr);
    fputc('\n', stderr);
    exit(1);
}

测试:
首先对服务器端进行执行。打开一个终端,执行下列指令:
编译:gcc echo_server.c -o eserver
执行:./eserver 9190
正常情况下程序将停留在此状态,因为服务器端调用的accept函数还未返回。
Linux系统基于TCP的回声(echo)服务器端/客户端(改写)_第1张图片
接下来运行客户端,打开另一个终端,执行下列指令:
编译:gcc echo_client.c -o eclient
运行:./eclient 127.0.0.1 9190
Linux系统基于TCP的回声(echo)服务器端/客户端(改写)_第2张图片
开始测试,发现当所输入字符串长度大于等于实际长度时,服务器返回给客户端的字符串是正确的,当字符串实际长度大于输入的字符串长度时,只输出之前向服务器输入的字符串长度所对应的字符串。
例如:
长度为7,字符串为hello,服务器返回hello;
长度为7,字符串为helloworld,服务器返回hellowo。

运行结果:
Linux系统基于TCP的回声(echo)服务器端/客户端(改写)_第3张图片

你可能感兴趣的:(TCP/IP网络编程作业)