结果输出:
------------------------------------------------------
客户端:
[email protected]:~/Public/C$ ./postBackCli.out 127.0.0.1
connect OK
aaa
aaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbb
c
c
#
close OK
[email protected]:~/Public/C$
------------------------------------------------------
服务器端:
[email protected]:~/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 \n"); exit(0); } if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ printf("create socket error: %s(errno: %d)\n", 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\n",argv[1]); exit(0); } if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){ printf("connect error: %s(errno: %d)\n",strerror(errno),errno); exit(0); } printf("connect OK\n"); str_cli(stdin,sockfd); close(sockfd); printf("close OK\n"); 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)\n",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)\n",strerror(errno),errno); exit(0); } //开始监听是否有客户端连接 if( listen(socket_fd, 10) == -1){ printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno); exit(0); } printf("======waiting for client‘s request======\n"); 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("\nfrom:%s,port:%d\n",(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"); }
时间: 2024-10-06 11:07:47