欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

客户端和服务端通信的多种函数的对比。linux 网络编程

程序员文章站 2022-06-06 08:30:05
...

第一种普通的read recv write

Makefile

#LOCAL_LIBRARY +=  -L./lib -lpal
#LOCAL_LDFLAGS += -lm -lopus -lwebsockets -lpthread -ldl
#LOCAL_CFLAGS += -I./include
#
#
TARGETS1 = client
TARGETS2 = service
CC:=gcc

SRCS1 = client.cc process.cc
SRCS2 = server.cc process.cc
OBJS1 = $(patsubst %.cc, %.o, $(SRCS1))
OBJS2 = $(patsubst %.cc, %.o, $(SRCS2))

CFLAGS += $(LOCAL_CFLAGS)
LDFLAGS += $(LOCAL_LIBRARY) $(LOCAL_LDFLAGS)


all: $(TARGETS1) $(TARGETS2)


$(TARGETS1):$(OBJS1)
    $(CC)  -o [email protected] $^  $(LDFLAGS) $(CFLAGS)

$(TARGETS2):$(OBJS2)
    $(CC)  -o [email protected] $^  $(LDFLAGS) $(CFLAGS)

$(OBJS1): %.o:%.cc
    $(CC) -c $< -o [email protected] $(CFLAGS)

$(OBJS2): %.o:%.cc
    $(CC) -c $< -o [email protected] $(CFLAGS)
clean :
    @rm -rf $(TARGETS1) $(OBJS1)

#.SUFFIXES:
.PHONY : all clean

客户端的处理函数

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
extern void sig_proccess(int signo);
extern void sig_pipe(int signo);
extern void process_conn_client(int signo);
static int s;
void sig_proccess_client(int signo)
{
    printf("Catch a exit signal\n");
    close(s);
    exit(0);
}
#define PORT 8888
int main(int argc,char *argv[])
{
    struct sockaddr_in server_addr;
    int err;

    if(argc == 1)
    {
        printf("PLS input server addr\n");
        return 0;
    }
    signal(SIGINT, sig_proccess);
    signal(SIGPIPE, sig_pipe);

    s = socket(AF_INET, SOCK_STREAM, 0);
    if(s < 0)
    {
        printf("socket error\n");
        return -1;
    }
    /*设置服务器地址*/
    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(PORT);

    inet_pton(AF_INET, argv[1], &server_addr.sin_addr);

    connect(s, (struct sockaddr*)&server_addr, sizeof(struct sockaddr));

    process_conn_client(s);
    close(s);
    return 0;
}

服务端的处理函数

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/unistd.h>
#include <netinet/in.h>
#include <signal.h>
extern void sig_proccess(int signo);
extern void process_conn_server(int signo);
#define PORT 8888
#define BACKLOG 2
int main(int argc, char *argv[])
{
    int ss,sc;
    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
    int err;
    pid_t pid;
    signal(SIGINT, sig_proccess);
    signal(SIGPIPE, sig_proccess);

    ss = socket(AF_INET, SOCK_STREAM, 0);
    if(ss < 0)
    {
        printf("socket error\n");
        return -1;
    }

    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(PORT);

    err = bind(ss, (struct sockaddr*)&server_addr, sizeof(server_addr));
    if(err < 0)
    {
        printf("listen error %d \n",errno);
        return -1;
    }
    err =listen(ss, BACKLOG);
    if(err < 0)
    {
        printf("listen error\n");
        return -1;
    }

    for(;;)
    {
        socklen_t addrlen = sizeof(struct sockaddr);
        sc = accept(ss, (struct sockaddr*)&client_addr, &addrlen);
        if(sc < 0)
        {
            continue;
        }

        pid = fork();
        if( pid == 0 )
        {
            close(ss);
            process_conn_server(sc);
        }else{
            close(sc);
        }
    }
}

公用的处理函数

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
/*服务器对客户端的处理*/
void process_conn_server(int s)
{
    ssize_t size = 0;
    char buffer[1024];                      /*数据的缓冲区*/

    for(;;){                                /*循环处理过程*/
        size = recv(s, buffer, 1024,0);
                                /*从套接字中读取数据放到缓冲区buffer中*/
        if(size == 0){                      /*没有数据*/
            return;
        }

        sprintf(buffer, "%d bytes altogether\n", size);
                                /*构建响应字符,为接收到客户端字节的数量*/
        send(s, buffer, strlen(buffer)+1,0);        /*发给客户端*/
    }
}

/*客户端的处理过程*/
void process_conn_client(int s)
{
    ssize_t size = 0;
    char buffer[1024];                          /*数据的缓冲区*/

    for(;;){                                    /*循环处理过程*/
        size = read(0, buffer, 1024);
                                /*从标准输入中读取数据放到缓冲区buffer中*/
        if(size > 0){                           /*读到数据*/
            send(s, buffer, size,0);            /*发送给服务器*/
            size = recv(s, buffer, 1024,0); /*从服务器读取数据*/
            write(1, buffer, size);             /*写到标准输出*/
        }
    }
}

/*信号SIGINT的处理函数*/
void sig_proccess(int signo)
{
    printf("Catch a exit signal\n");
    _exit(0);
}

/*信号SIGPIPE的处理函数*/
void sig_pipe(int sign)
{
    printf("Catch a SIGPIPE signal\n");

    /*释放资源*/
}

###