1、程序实现的功能
(1)、程序pragram_a作为服务器,监听客户端发送过来的ip地址,服务端判断该ip地址是否在线
(2)、程序pragram_b作为客户端,向服务器发送ip地址,发送完后自行退出
2、代码实现
总共三个文件:pragram_a.c、pragram_b.c、makefile
//服务器源码:pragram_a.c
#include <stdio.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <stddef.h>
#include <string.h>
#include<stdlib.h>
#include<unistd.h>
// the max connection number of the server
#define MAX_CONNECTION_NUMBER 100
/* * Create a server endpoint of a connection. * Returns fd if all OK, <0 on error. */
int unix_socket_listen(const char *servername)
{
int fd;
struct sockaddr_un un;
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
{
return(-1);
}
int len, rval;
unlink(servername); /* in case it already exists */
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
strcpy(un.sun_path, servername);
len = offsetof(struct sockaddr_un, sun_path) + strlen(servername);
/* bind the name to the descriptor */
if (bind(fd, (struct sockaddr *)&un, len) < 0)
{
rval = -2;
}
else
{
if (listen(fd, MAX_CONNECTION_NUMBER) < 0)
{
rval = -3;
}
else
{
return fd;
}
}
close(fd);
return rval;
}
int unix_socket_accept(int listenfd, uid_t *uidptr)
{
int clifd, len, rval;
time_t staletime;
struct sockaddr_un un;
struct stat statbuf;
len = sizeof(un);
if ((clifd = accept(listenfd, (struct sockaddr *)&un, &len)) < 0)
{
return(-1);
}
/* obtain the client's uid from its calling address */
len -= offsetof(struct sockaddr_un, sun_path); /* len of pathname */
un.sun_path[len] = 0; /* null terminate */
if (stat(un.sun_path, &statbuf) < 0)
{
rval = -2;
}
else
{
if (S_ISSOCK(statbuf.st_mode))
{
if (uidptr != NULL) *uidptr = statbuf.st_uid; /* return uid of caller */
unlink(un.sun_path); /* we're done with pathname now */
return clifd;
}
else
{
rval = -3; /* not a socket */
}
}
close(clifd);
return(rval);
}
void unix_socket_close(int fd)
{
close(fd);
}
/* return 0 is online; return 1 is offline */
int ip_is_online(char* ip)
{
char res[1024] = "ping -c2 -i0.2 -W1 ";
strcat(res,ip);
strcat(res, ">> server.log");
return system(res);
}
int main(void)
{
int listenfd;
listenfd = unix_socket_listen("foo.sock");
if(listenfd<0)
{
printf("Error[%d] when listening...\n",errno);
return 0;
}
printf("\nServer is start\n");
printf("=====================================================\n");
printf(" ip status \n");
int size;
char rvbuf[2048];
while(1)
{
uid_t uid;
int connfd;
connfd = unix_socket_accept(listenfd, &uid);
if(connfd<0)
{
printf("Error[%d:%s] when accepting...\n",errno,strerror(errno));
break;
}
//===========接收==============
memset(rvbuf,0,sizeof(char)*2048);
size = recv(connfd, rvbuf, sizeof(rvbuf), 0);
if(size>0)
{
if(ip_is_online(rvbuf) == 0)
{
printf(" %-20s online\n",rvbuf);
}
else
printf(" %-20s offline\n",rvbuf);
}
if(size==-1)
{
printf("Error[%d] when recieving Data:%s.\n",errno,strerror(errno));
break;
}
unix_socket_close(connfd);
}
unix_socket_close(listenfd);
printf("Server exited.\n");
return 0;
}
//客户端源码:pragram_b.c
#include <stdio.h>
#include <stddef.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
/* Create a client endpoint and connect to a server. Returns fd if all OK, <0 on error. */
int unix_socket_conn(const char *servername)
{
int fd;
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) /* create a UNIX domain stream socket */
{
return(-1);
}
int len, rval;
struct sockaddr_un un;
memset(&un, 0, sizeof(un)); /* fill socket address structure with our address */
un.sun_family = AF_UNIX;
sprintf(un.sun_path, "scktmp%5d",getpid());
len = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
unlink(un.sun_path); /* in case it already exists */
if (bind(fd, (struct sockaddr *)&un, len) < 0)
{
rval = -2;
}
else
{
/* fill socket address structure with server's address */
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
strcpy(un.sun_path, servername);
len = offsetof(struct sockaddr_un, sun_path) + strlen(servername);
if (connect(fd, (struct sockaddr *)&un, len) < 0)
{
rval = -4;
}
else
{
return fd;
}
}
close(fd);
return rval;
}
void unix_socket_close(int fd)
{
close(fd);
}
int main(int argc, char* argv[])
{
int flag = 0;
int k;
for(k = 0; k < argc; k++)
{
if(strcmp(argv[k],"-c") == 0)
{
flag = 1;
k++;
}
if(flag == 1)
{
int connfd = 0;
connfd = unix_socket_conn("foo.sock");
if(connfd<0)
{
printf("Error[%d] when connecting...",errno);
return 0;
}
int size = 0;
size = send(connfd, argv[k], strlen(argv[k]), 0);
if(size > 0)
{
printf("send ip---->%s\n", argv[k]);
}
else if(size == -1)
{
printf("Error[%d] when sending data:%s.\n",errno, strerror(errno));
break;
}
unix_socket_close(connfd);
sleep(1);
}
}
return 0;
}
#编译脚本:makefile
#This is the makefile of EpollTest
.PHONY:all
all:pragram_a pragram_b
server:
gcc spragram_a.c -o pragram_a
client:
gcc pragram_b.c -o pragram_b
clean:
rm -f pragram_a pragram_b server.log foo.sock scktmp*
3、编译及运行结果
注:此程序在ubuntu和centos下运行正常