//获得本机IP地址
char* GetLocalAddr()
{
char szName[255];
char* addrIP;
struct in_addr addr;
struct hostent * host;
memset(szName,0,255);
if(gethostname(szName,255)==0)
{
host = gethostbyname(szName);
if(host->h_addr_list[0])
{
memmove(&addr,host->h_addr_list[0],4);
addrIP = inet_ntoa(addr);
}
}
return addrIP;
}
//守护进程的创建
守护进程(Daemon)是指其他多任务操作系统中在后台执行的计算机程序,并不会接受计算机用户的直接控制,其好处是不占用终端。
void Daemonize()
{
if(fork()>0) exit(0);//避免挂起控制终端,将守护进程放入后台执行。
setsid(); //脱离控制终端和进程组,使该进程成为会话组长,并与原来的登录会话和进程组脱离。此时进程已经成为无终端的会话组长,但它可以重新申请打开一个控制终端。
if(fork()>0) exit(0);//为了这种情况发生,再次调用fork函数使该进程不再成为会话组长,从而禁止重新打开控制终端。由此,父进程(会话组长)退出,子进程继续执行,并不再拥有打开控制终端的能力。
socket服务程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#define MAX_RECV_LEN 100
#define MAX_PENDING_CONNECTS 4
//服务程序的侦听函数
int Listening(int port)
{
int sockfd = -1, reuse = 1;
struct sockaddr_in my_addr;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==1)//创建流式Socket
{
perror("Alocating socket failed");
return -1;
}
setsockopt(sockfd, SOL_SOCKET,SO_REUSEADDR,(const char*)&reuse,sizeof(reuse));//设置Socket重用
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(port);
my_addr.sin_addr.s_addr=hton1(INADDR_ANY);
if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(my_addr))==-1) //绑定端口
{
perror("Binging failed");
close(sockfd);
return -1;
}
if(listen(sockfd,MAX_PENDING_CONNECTS)==-1)//侦听
{
perror("Listening failed");
close(sockfd);
return -1;
}
return sockfd;
}
//服务与客户程序通信的主要调用函数
int SocketServer(int nPort, char * szReply, int nReplyLen, char * szRequest)
{
int sockfd = -1, client_fd=-1,iret;
struct sockaddr *accept_sin;
int accept_sin_len = sizeof(accept_sin);
sockfd = Listening(nPort);
if(sockfd ==-1) return -1;
//接受客户连接请求
client_fd = accept(sockfd, (struct sockaddr*)&accept_sin, (int*)&accept_sin_len);
close(sockfd);
if(client_fd==-1)
{
perror("Accepting connection with client failed");
return -1;
}
iret = recv(client_fd, szRequest, MAX_RECV_LEN,0);//接受数据
szRequest[iret]=0;
if(send(client_fd, szReply,nRepleyLen,0)==-1) //发送回应
perror("Sending data to the client failed");
close(client_fd);
return 0;
}
//服务与客户程序通信的主函数
void main()
{
char szRequest[255];
Daemonize();
while(1)
{
if(SocketServer(2004,"I am the server!",20, szRequest)!=-1)
printf("%s\n", szRequest);
}
}
socket客户程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#define MAX_RECV_LEN 100
//建立与服务程序连接函数
int GetConnect(char* host, int port)
{
int sockfd;
struct sockaddr_in serv_addr;
struct hostent *phostent = NULL;
if((socket=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("Alocating socket failed");
return -1;
}
serv_addr.sin_family=AF_INET;
if((phostent=gethostbyname(host))==NULL)
{
perror("Unable to get the host name");
close(sockfd);
return -1;
}
memcpy((char*)&(serv_addr.sin_addr),phostent->h_addr,phostent->h_lenght);
serv_addr.sin_port=htons(port);
if(connect(sockfd,(struct sockaddr*)&serv_addr, sizeof(serv_addr))==-1)
{
perror("Connecting to the server failed");
colse(sockfd);
return -1;
}
return sockfd;
}
//客户程序与服务程序通信的主要调用函数
void SocketClient(char* szHost, int nPort, char* szRequest, int nRequsetLen,char* szReply)
{
int sockfd = -1,iret;
sockfd = GetConnect(szHost,nPort);
if(sockfd==-1) return ;
if(send(sockfd,szRequest, nRequestLen,0)==-1)//向服务程序发生请求
{
perror("Sending data to the server failed");
}
iret = recv(sockfd, szReply, MAX_RECV_LEN,0) //接受数据
szReply[iret]=0;
close(sockfd);
}
void main()
{
char szReply[255];
SicketClient(GetLocalAddr(),2004,"I am the client",20,szReply);
printf("%s\n",szReply);
}