【linux 网络编程 求和】Unix Socket 网络编程 回射服务器 客户端输入俩个整数服务器经过计算返回值客户端接受并且输出。

开发环境

Red Hat Enterprise Linux Server release 7.0 (Maipo)

Client相关代码:

//client.c
#include "myhead.h"

int main(int argc, char **argv)
{
    int sockfd;
    struct sockaddr_in servaddr;

    if (argc != 2) {
        printf("Usages :tcpcli1 <IPaddres>\n");
        return -1;
    }

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("socket error:%s\n", strerror(errno));
        return -1;
    }

    memset(&servaddr, 0x00, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERV_PORT);
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) < 0) {
        printf("inet_pton error:%s\n", strerror(errno));
        return -1;
    }

    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        printf("connect error:%s\n", strerror(errno));
        return -1;
    }

    str_cli(stdin, sockfd);
    exit(0);
}
//myhead.h
/*================================================================
*   Copyright (C) 2019 Sangfor Ltd. All rights reserved.
*   
*   文件名称:myhead.h
*   创 建 者:gaojie
*   创建日期:2019年04月08日
*   描    述:定义网络编程常用的头文件,宏。
*
================================================================*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>

#include <sys/select.h>
#include <sys/time.h>


#define max(a,b)    ((a) > (b) ? (a) : (b))

#define SERV_PORT 9877
#define MAXLINE 4096

void str_cli(FILE *fp, int sockfd) ;//回射 select shutdown mul
//str_cli.c
/*================================================================
*   Copyright (C) 2019 Sangfor Ltd. All rights reserved.
*   
*   文件名称:str_cli.c
*   创 建 者:gaojie
*   创建日期:2019年04月08日
*   描    述:
*
================================================================*/

#include "myhead.h"

void str_cli(FILE *fp, int sockfd) {
    char sendline[MAXLINE], recvline[MAXLINE];
    fd_set rset;
    int maxfdpl,stdineof;
    int n;

    stdineof = 0;
    FD_ZERO(&rset);

    //while (fgets(sendline, MAXLINE, fp) != NULL) {
    for(;;){
        if(stdineof == 0)
            FD_SET(fileno(fp),&rset);
        FD_SET(sockfd,&rset);
        maxfdpl = max(fileno(fp),sockfd) + 1;
        n = select(maxfdpl,&rset,NULL,NULL,NULL);
        if(n == -1)
        {
            printf("select error:%s",strerror(errno));
            return ;
        }
        if(FD_ISSET(sockfd,&rset))
        {
            if((n = read(sockfd,recvline,MAXLINE)) == 0)
            {
                if(stdineof == 1)
                    return;
                else
                {
                    printf("str_cli:server terminated prematurely!\n");
                    exit(0) ;
                }
            }
             recvline[n] = '\0';
            printf("%s\n",recvline);
        }
        if(FD_ISSET(fileno(fp),&rset))
        {
            if(fgets(sendline, MAXLINE, fp) == NULL)
            {
                stdineof = 1;
                shutdown(sockfd,SHUT_WR);
                FD_CLR(fileno(fp),&rset);
                continue;
            }
            if(write(sockfd,sendline,strlen(sendline)) < 0)
            {
                printf("write error:%s\n",strerror(errno));
            }
        }
        
        memset(sendline, 0x00, MAXLINE);
        memset(recvline, 0x00, MAXLINE);
    }
}

Server相关代码:

//server.c
#include "myhead.h"

typedef void sigfunc(int);
sigfunc* signal(int signo,sigfunc *func)
{
    struct sigaction act,oact;
    act.sa_handler=func;
    sigemptyset(&act.sa_mask);
    act.sa_flags=0;
    if(signo==SIGALRM)
    {
#ifdef SA_INTERRUPT
        act.sa_flags|=SA_INTERRUPT;
#endif
    }else{
#ifdef SA_RESTART
        //act.sa_flags|=SA_RESTART;
#endif
    }
    if(sigaction(signo,&act,&oact)<0)
        return(SIG_ERR);
    return(oact.sa_handler);
}
void sig_chld(int signo)
{
    pid_t pid;
    int   stat;

   while(( pid = waitpid(-1,&stat,WNOHANG))>0)
        printf("child %d terminated\n",pid);
    return;
}
void ChangeBuff(char *writebuff,const char *buff)
{
    if(writebuff==NULL||buff==NULL) return;
    int i=0;
    for(i=0;buff[i]!='\0';i++)
    {
        if(isupper(buff[i]))
            writebuff[i]=tolower(buff[i]);
        else if(islower(buff[i]))
            writebuff[i]=toupper(buff[i]);
        else
            writebuff[i]=buff[i];
    }
}
void MulToInt(const char *buff,char *writebuff)
{
    if(writebuff==NULL||buff==NULL)return;
    int element1=0,element2=0;
    while(!isdigit(*buff)) buff++;
    while(*buff!=' ' && isdigit(*buff))
    {
        element1=element1*10 + (*buff - '0');
        buff++;
    }
    buff++;
    while(*buff!='\0' && isdigit(*buff))
    {
        element2=element2*10 + (*buff - '0');
        buff++;
    }
    int res = element1 * element2;
    char tmpstr[256]={0};
    sprintf(tmpstr,"%d",res);
    int i = 0;
    while(tmpstr[i]!='\0')
    {
        *writebuff = tmpstr[i++];
        writebuff++;
    }
}
void str_echo(int sockfd) {
    ssize_t n;
    char buf[MAXLINE];
    char writebuff[MAXLINE];

    for(;;) {
        if ((n = read(sockfd, buf, MAXLINE)) == 0) 
                return;
            MulToInt(buf,writebuff);
            if (write(sockfd, writebuff, n) < 0) {
                printf("write error:%s\n", strerror(errno));
            }
            memset(buf, 0x00, MAXLINE);
        

        if (n < 0 && errno != EINTR) {
            printf("str_echo: read error:%s\n", strerror(errno));
        }
    }
}

int main(int argc, char **argv)
{
    int listenfd, connfd;
    pid_t childpid;
    socklen_t clilen;
    struct sockaddr_in cliaddr, servaddr;

    if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        printf("socket error:%s\n", strerror(errno));
        return -1;
    }

    memset(&servaddr, 0x00, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(SERV_PORT);

    if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
        printf("bind error:%s\n", strerror(errno));
        return -1;
    }

    if (listen(listenfd, LISTENQ) < 0) {
        printf("listen error:%s\n", strerror(errno));
        return -1;
    }
    
    signal(SIGCHLD,sig_chld);
    for(;;) {
        clilen = sizeof(cliaddr);
        if ((connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen)) < 0) {
            if(errno==EINTR)
            {
                printf("Interrupted system call but continue\n");
                continue;
            }
            else
            {
                printf("acctop error!\n:%s",strerror(errno));
                return 0;
            }
        }

        if ((childpid = fork()) == 0) {
            if (close(listenfd) < 0) {
                printf("close listenfd error:%s\n", strerror(errno));
            }
            str_echo(connfd);
            exit(0);
        }

        if (close(connfd) < 0) {
            printf("close connfd error:%s\n", strerror(errno));
        }
    }

}
//myhead.h
/*================================================================
*   Copyright (C) 2019 Sangfor Ltd. All rights reserved.
*   
*   文件名称:myhead.h
*   创 建 者:gaojie
*   创建日期:2019年04月08日
*   描    述:定义网络编程常用的头文件,宏。
*
================================================================*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <errno.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>
#include <stdlib.h>
#include <ctype.h>
#include <netinet/in.h>

#define LISTENQ 5


#define max(a,b)    ((a) > (b) ? (a) : (b))

#define SERV_PORT 9877
#define MAXLINE 4096

<附加功能>:

客户端可以监测到服务器的断开(socket),服务器也可以监测到客户端的断开(waitpid)

测试结果:

客户端:

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值