Socket 入门- 客户端回射程序

结果输出:
------------------------------------------------------
客户端:
xx@xxxxxx:~/Public/C$ ./postBackCli.out 127.0.0.1
connect OK
aaa
aaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbb
c
c
#
close OK
xx@xxxxxx:~/Public/C$ 
------------------------------------------------------
服务器端:
xx@xxxxxx:~/Public/C$ ./postBackSrv.out 
======waiting for client's request======
from:127.0.0.1,port:45050
---------华丽的分割线---------
postBackCli.c

 
//main函数中详细注释可查看博主--获取服务器时间实例--博文,内有较详细注释
//部分细节写的代码较草率,博主新入门,前辈勿喷
#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include<errno.h> 
#include<sys/types.h> 
#include<sys/socket.h> 
#include<netinet/in.h> 
  
#define MAXLINE 4096 
void str_cli(FILE *fp,int sockfd);

int main(int argc, char** argv) 
{ 
    int sockfd, n,rec_len; 
    char recvline[4096], sendline[4096]; 
    char buf[MAXLINE]; 
    struct sockaddr_in servaddr; 
    
    if( argc != 2){ 
    printf("usage: ./client 
"); 
    exit(0); 
    } 
    
    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ 
    printf("create socket error: %s(errno: %d)
", strerror(errno),errno); 
    exit(0); 
    } 
    
    memset(&servaddr, 0, sizeof(servaddr)); 
    servaddr.sin_family = AF_INET; 
    servaddr.sin_port = htons(8000); 
    if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){ 
    printf("inet_pton error for %s
",argv[1]); 
    exit(0); 
    } 
    
    if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){ 
    printf("connect error: %s(errno: %d)
",strerror(errno),errno); 
    exit(0); 
    } 
    printf("connect OK
");
    str_cli(stdin,sockfd);
    close(sockfd); 
    printf("close OK
");
    exit(0); 
} 
//回射处理函数
void str_cli(FILE *fp,int sockfd)
{
    char sendline[MAXLINE],recvline[MAXLINE];//定义两个缓冲区
    while (fgets(sendline,MAXLINE,fp)!= NULL)//从标准输入输入到sendline中
    {
      if(sendline[0] == '#')break;//如果输入#则退出循环,同时结束本次回射程序
      write(sockfd,sendline,strlen(sendline));//将sendline缓冲区中的数据写到"套接字"
      read(sockfd,recvline,MAXLINE);//从套接字读数据到recvline中
      fputs(recvline,stdout);//从recvline缓冲区读出到标准输出中
      bzero(recvline,sizeof(recvline));//清空接受缓冲区,每次都是最新的数据【需注意】
    }
}

  postBackSrv.c

#include<stdio.h> 
#include<stdlib.h> 
#include<string.h> 
#include<errno.h> 
#include<sys/types.h> 
#include<sys/socket.h> 
#include<netinet/in.h> 
#define DEFAULT_PORT 8000 //默认端口 
#define MAXLINE 4096 
void str_echo(int sockfd);
int main(int argc, char** argv) 
{ 
    int socket_fd, connect_fd; 
    struct sockaddr_in servaddr,cliaddr; 
    char buff[MAXLINE],temp[MAXLINE]; 
    int n;
    uint32_t len;
     //初始化Socket 
    if( (socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 )
    { 
    printf("create socket error: %s(errno: %d)
",strerror(errno),errno); 
    exit(0); 
    } 
    //初始化 
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET; 
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址设置成INADDR_ANY,让系统自动获取本机的IP地址。 
    servaddr.sin_port = htons(DEFAULT_PORT);//设置的端口为DEFAULT_PORT 
  
    //将本地地址绑定到所创建的套接字上 
    if( bind(socket_fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){ 
    printf("bind socket error: %s(errno: %d)
",strerror(errno),errno); 
    exit(0); 
    } 
    //开始监听是否有客户端连接 
    if( listen(socket_fd, 10) == -1){ 
    printf("listen socket error: %s(errno: %d)
",strerror(errno),errno); 
    exit(0); 
    } 
    printf("======waiting for client's request======
"); 
    while(1){ 
    len=sizeof(cliaddr);
    //阻塞直到有客户端连接 
        connect_fd = accept(socket_fd, (struct sockaddr *)&cliaddr,&len);
 
    //向客户端发送回应数据
        if(!fork())//进入子进程,在子进程服务终止时会给父进程发送一个SIGCHLD信号,父进程未处理,子进程进入僵死状态,必须清理僵死状态,这里牵扯Unix信号的处li.
    {    //子进程在其内部关闭监听套接字
        close(socket_fd);
               str_echo(connect_fd);
        //输出客户协议信息
        printf("
from:%s,port:%d
",(char *)inet_ntop(AF_INET,&cliaddr.sin_addr,temp,sizeof(temp)),ntohs(cliaddr.sin_port));
     close(connect_fd); 
     exit(0); 
      } 
        close(connect_fd); 
    } 
    close(socket_fd); 
} 
void str_echo(int sockfd)
{
    ssize_t n;
    char buf[MAXLINE];
    while(( n=read(sockfd,buf,MAXLINE))>0)
      write(sockfd,buf,n);
    if(n<0 && errno==EINTR)
     perror("str_echo:red error");
}

  

原文地址:https://www.cnblogs.com/A--Q/p/5665131.html