unix下实现echo机制
linux下的echo命令:echo命令的功能是在显示器上显示一段文字,一般起到一个提示的作用。该命令的一般格式为: echo [ -n ] 字符串其中选项n表示输出文字后不换行;字符串能加引号,也能不加引号。用echo命令输出加引号的字符串时,将字符串原样输出;用echo命令输出不加引号的字符串时,将字符串中的各个单词作为字符串输出,各字符串之间用一个空格分割。功能说明:
linux下的echo命令:
echo命令的功能是在显示器上显示一段文字,一般起到一个提示的作用。
该命令的一般格式为: echo [ -n ] 字符串
其中选项n表示输出文字后不换行;字符串能加引号,也能不加引号。用echo命令输出加引号的字符串时,将字符串原样输出;用echo命令输出不加引号的字符串时,将字符串中的各个单词作为字符串输出,各字符串之间用一个空格分割。
功能说明:显示文字。
语 法:echo [-ne][字符串]或 echo [--help][--version]
补充说明:echo会将输入的字符串送往标准输出。输出的字符串间以空白字符隔开, 并在最后加上换行号。
参 数:-n 不要在最后自动换行
-e 若字符串中出现以下字符,则特别加以处理,而不会将它当成一般
文字输出:
–help 显示帮助
–version 显示版本信息
源代码如下:
客户端:
//this is the client of the echo
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#define UNIX_SOCK_PATH "/tmp/my_unix_socket"
int main(int argc,char *argv[])
{
int conn_fd,serv_len;
struct sockaddr_un serv_addr;
int ret;
char send_line[100],recv_line[100];
conn_fd=socket(AF_UNIX,SOCK_STREAM,0);
bzero(&serv_addr,sizeof(serv_addr));
serv_addr.sun_family=AF_UNIX;
strcpy(serv_addr.sun_path,UNIX_SOCK_PATH);
serv_len=strlen(serv_addr.sun_path)+sizeof(serv_addr.sun_family);
ret=connect(conn_fd,(struct sockaddr *)&serv_addr,serv_len);
if(ret==-1)
{
perror("client connect failed!\n");
exit(1);
}
while(1)
{
if(fgets(send_line,100,stdin)==NULL)
{
printf("receives end of the file\n");
exit(0);
}
else{
sendagain:
ret=send(conn_fd,send_line,strlen(send_line),0);
if(ret<0 && errno!=EINTR)
{
perror("send failed\n");
exit(1);
}
else if(ret<0&&errno==EINTR) //EINTR which means the send interuputd by signal
goto sendagain; //so you should try it again
recvagain:
ret=recv(conn_fd,recv_line,100,0);
if(ret<0 && errno!=EINTR)
{
perror("recv failed\n");
exit(1);
}
else if(ret<0&&errno==EINTR)
goto recvagain;
if(ret==0)
{
fprintf(stderr,"peer close the connection.\n");
exit(0);
}
if(ret>0)
{
recv_line[100]='\0';
fprintf(stdout,recv_line);
}
}
}
exit(0);
}
服务器端:
//this is the server of the echo
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <signal.h>
#include <sys/wait.h>
#include <unistd.h>
#define LISTENQ 10
#define UNIX_SOCK_PATH "/tmp/my_unix_socket"
/*
struct sockaddr_un
{
short int sun_family;
char sun_path[104];
};
*/
void echo_service(int conn_fd);
int main(int argc,char ** argv)
{
int listen_fd,conn_fd;
int serv_len,cli_len;
pid_t chld_pid;
struct sockaddr_un cli_addr,serv_addr;
int ret;
int re_use_addr=1;
int fd;
int link;
listen_fd=socket(AF_UNIX,SOCK_STREAM,0);
if(listen_fd==-1)
{
printf("create listen_fd failed!\n");
exit(1);
}
serv_addr.sun_family=AF_UNIX;
strcpy(serv_addr.sun_path,UNIX_SOCK_PATH);
serv_len=strlen(serv_addr.sun_path)+sizeof(serv_addr.sun_family);
/*
the system will create the file which is located in the fixed path, so we should delete the file in that
path now,this can avoid the bind()function successful used
*/
unlinkagain:
link=unlink(serv_addr.sun_path);
if(link==-1&&errno!=EINTR)
{
perror("unlink failed!\n");
exit(1);
}
else if(link==-1&&errno==EINTR)
{
goto unlinkagain;
}
setsockopt(listen_fd,SOL_SOCKET,SO_REUSEADDR,(void *)&re_use_addr,sizeof(int)); //this function is to reuse the port which the other
//process used before
ret=bind(listen_fd,(struct sockaddr *)&serv_addr,serv_len);
if(ret<0)
{
perror("bind server port failed!\n");
exit(1);
}
listen(listen_fd,LISTENQ);
while(1)
{
cli_len=sizeof(cli_addr);
printf("the server is wanting for accept new connecion\n");
conn_fd=accept(listen_fd,(struct sockaddr*)&cli_addr,&cli_len);
if(conn_fd<0 && errno==EINTR)
continue;
else if(conn_fd<0)
{
perror("accept socket failed!\n");
exit(1);
}
printf("the server create a new connection.\n");
if((chld_pid=fork())==0)
{
close(listen_fd);
echo_service(conn_fd);
exit(0);
}
close(conn_fd);
while(waitpid(-1,NULL,WNOHANG)>0);
}
}
void echo_service(int conn_fd)
{
ssize_t nline;
char recv_line[100];
int ret;
while(1)
{
nline=recv(conn_fd,recv_line,100,0);
if(nline<0 && errno!=EINTR)
{
perror("recv error in echo service");
exit(1);
}
else if(nline<0 &&errno==EINTR)
{
continue;
}
if(nline==0)
break;
if(nline>0)
{
recv_line[nline]='\0';
sendagain:
ret=send(conn_fd,recv_line,nline,0) ;
if(ret<0 && errno!=EINTR)
{
perror("send error\n");
exit(1);
}
else if(ret<0 && errno==EINTR)
goto sendagain;
}
}
}
更多推荐
所有评论(0)