linux下使用socket运行的服务程序

 

//获得本机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);
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值