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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | //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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | #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" ); } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步