Socket编程基础代码

单次服务器server(又可称为迭代式服务器程序)

#include "unp.h"

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

    listenfd = Socket(FP_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_finally = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADRR_ANY);
    servaddr.sin_port = htons(SERVPORT);

    Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));
    
    Listen(listenfd, BACKLOG);    

    for(;;){
        clilen = sizeof(cliaddr);
        connfd = Accept(listenfd, (SA*)&cliaddr, clilen);
        Close(listenfd);
        str_echo(connfd);
        Close(connfd);
    }
    return 0;
}


void str_echo(int sockfd){
    ssize_t n;
    char buf[MAXLINE];
again:
    while((n = read(sockfd, buf , MAXLINE))>0){
        Writen(sockfd, buf, n);
    }
    if(n<0 && erron == EINTR)
        goto again;
    else if(n<0)
        err_sys("str_echo: read error");

}

单次服务器多次循环成为迭代式服务器,其中for()控制循环次数。假如循环五次,则只需要改for循坏,改为如下

for(int i = 0 ; i < 5 ; i++){
    
}

 

多进程服务器

#include "upn.h"

char buffer[BUFFER_SIZE];
int main(int argc, char* argcv[]){
    int listenfd, connfd;
    size_t clilen;
    struct sockaddr_in cliaddr,servaddr;
    
    signal(SIGCHLD, SIG_IGN);

    listenfd = Socket(PF_INET, SOCK_STREAM, 0);
    
    bzero(&servaddr,sizeof(seraddr));
    seraddr.sin_family = AF_INET;
    seraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    seraddr.sin_port = htons(SERVPORT)

    Bind(listenfd, (struct sockaddr_in*)& servaddr, sizeof(servaddr));
    
    Listen(listenfd, BACKLOG);
  
    while(1){
        clilen = sizeof(cliaddr);
        connfd = Accept(listenfd, (struct sockaddr_in*)&cliaddr, clilen);
        //开始做判断了
        if(connfd < 0 && connfd == EINTR) continue;
        if(Fork() == 0){
            Close(listenfd);
            str_echo2(connfd, buffer);
            Close(connfd);
            return 0
        }
        Close(listenfd);

    }
    Close(connfd);
    Return 0;
}

void str_echo2(int sockfd, char* buf)
{
    ssize_t n;
    while (1) {
        n = Read(sockfd, buf, BUFFER_SIZE);
        if (n > 0)
            Write(sockfd, buf, n);
        else
            return;
    }
}

ssize_t Read(int fd, void *ptr, size_t nbytes)
{
    ssize_t n;
    if ( (n = read(fd, ptr, nbytes)) == -1){
        if (errno == ECONNRESET) {
            err_msg("reset by peer");
            return 0;
        }
        else err_sys("read error");
    }
    return(n);
}

 

单次client

#include"unp.h"

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

    if(argc!=2){
        err_quit("");
    }
    
    sockfd = Socket(PF_INET, SOCK_STERAM, 0);
    
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERV_PORT);
    Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

    Connect(sockfd, (SA*)&servaddr, sizeof(servaddr));
    
    str_cli(stdin, sockfd);

    exit(0);
}

void str_cli(FILE *fp, int sockfd){
    char sendline[MAXLINE],recvline[MAXLINE];
  
    while(Fgets(sendline, MAXLINE, fp)!=NULL){
        Writen(sockfd, sendline, sizeof(sendline));

        if(Readline(sockfd, recvline, MAXLINE)==0) //服务器过早终止
            err_quit("str_cli: server terminated permaturely");
        
        Fput(recvline, stdout); 
    }  
    
}

将上述fp改为标准输入,也可以写为如格式:

#define PORT 1234

#define MAXLINE 100


int main(){
    
    /*
      同上
          */
    str_cli(sockfd);
       
}

void str_cli(int sockfd){
    char sendline[MAXLINE],readline[MAXLINE];
    
    char time[100];
    int i,datanum=0;    

    while(scanf("%s",time)){
        Writen(sockfd, time, sizeof(time));
        datanum = read(sockfd, readline, MAXLINE);
        recvline[datanum] = '\0';
        printf("服务器返回消息:%s",recvline);
    }
}

注意: (struct sockaddr_in *)&servaddr 和 (SA*)&servaddr的用法和意义是一样的,但是由于前者是linux包,后者是unp包,所以表达不同。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值