最新消息:

Linux Socket 学习笔记3–实现一个简单的C/S程序

C/C++ admin 3201浏览 0评论

之前主要学习了socketpair函数的操作,顺带复习了几个常用函数(open(2),write(2),pipe(2),time(2)等)。今天就来个综合应用,做一个基于socketpair函数的客户/服务通信程序。

程序的基本思想是:首先,用fork函数生成一个子进程,父进程作服务端,子进程作客户端,由客户端向服务端发送要求时间的格式,服务端接受请求并返回结果。

先把代码贴上,待会分析。

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
**   Client/Server Example Using socketpair(2)
*/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include    
 
int main(int argc,char **argv)
{
    int z;      // Status return code
    int s[2];       //Pair of sockets
    char *msgp;     //A message pointer
    int mlen;        //Message length
    char buf[80];       //Work buffer
    pid_t chpid;        // Child PID   
 
    //Create a pair of local sockets :
    z = socketpair(AF_LOCAL,SOCK_STREAM,0,s);
 
    if ( z == -1 )
    {
        fprintf(stderr,"%s: socketpair(2)n",strerror(errno));
        return 1;   //create socket failed
    }
 
    //Now fork() into two processes :
    if ( (chpid = fork()) < 0 )
    {
        fprintf(stderr,"%s: fork(2)n",strerror(errno));
        return 2;   //Failed to fork
    }
    else if ( chpid == 0 )
    {
        /*
       * This is the child process (client) :
       */
        char rxbuf[80]; /* Receive buffer */
        printf("Parent PID is %ldn",(long)getppid());
        close(s[0]);    /* Server uses s[0] */
        s[0] = -1;      /* Forget this unit */
 
        msgp = "%A %d-%b-%Y %l:%M %p";  //client message
        mlen = strlen(msgp);
        printf("Child sending request '%s'n",msgp);
        fflush(stdout);
 
    // Write a request to the server :
        z = write(s[1],msgp,mlen);
 
        if ( z < 0 )
        {
            fprintf(stderr,"%s: write(2)n",strerror(errno));
            return 3;   //write failed;
        }
 
        /*
       * Now indicate that we will not be writing
       * anything further to our socket, by shutting
       * down the write side of the socket :
       */
        if ( shutdown(s[1],SHUT_WR) == -1 )
        {
            fprintf(stderr,"%s: shutdown(2)n", strerror(errno));
            return 4;   //shutdown failed
        }
 
       // Receive the reply from the server :
        z = read(s[1],rxbuf,sizeof(rxbuf));
        if ( z < 0 )
        {
            fprintf(stderr,"%s: read(2)n",strerror(errno));
            return 5;   //read failed
        }
 
        rxbuf[z] = 0;
        printf("Server returned '%s'n",rxbuf);
        fflush(stdout);
        close(s[1]);    /* Close our end now */
    }
    else
    {
    /*
       * This is the parent process (server) :
       */
        int status;         /* Child termination status */
        char txbuf[80];         /* Reply buffer */
        time_t td;          /* Current date & time */
        printf("Child PID is %ldn",(long)chpid);
        fflush(stdout);
        close(s[1]);    /* Client uses s[1] */
        s[1] = -1;      /* Forget this descriptor */
 
       // Wait for a request from the client :
        z = read(s[0],buf,sizeof(buf));
 
        if ( z < 0 )
        {
            fprintf(stderr,"%s: read(2)n",strerror(errno));
            exit(1);
        }
        /*
       * Put a null byte at the end of the
       * message we received from the client:
       */
        buf[z] = 0;
 
        /*
       * Now perform the server function on the
       * received message :
       */
        time(&td);          /* Get current time */
        strftime(txbuf,sizeof txbuf,buf,localtime(&td));      /* Input time */
 
        /*
       * Send back the response to client :
       */
        z = write(s[0],txbuf,strlen(txbuf));
 
        if ( z < 0 )
        {
            fprintf(stderr,"%s: write(2)n",strerror(errno));
            return 6;       //server write failed
        }
    close(s[0]);
 
    // Wait for the child process to exit..
    waitpid(chpid,&status,0);
    }
    return 0;
}

首先由socketpair()创建一个套接口,用于客户端和服务端的通讯,然后由fork()生成子进程(客户端)。

43-84行是客户端的执行代码。

91-133是服务端的执行代码。

因为套接口是全工模式的,所以可以让客户端在s[1]端进行读写操作,服务端在s[0]端进行读写操作,便于管理。

简单说来,就是客户端在s[1]写请求,服务端在s[0]读请求,然后服务端在s[0]写结果,最后由客户端在s[1]读出。

程序比较简单,很有条理,又有注释,很好懂。

程序结果:

Parent PID is 4950
Child sending request ‘%A %d-%b-%Y %l:%M %p’
Child PID is 4951
Server returned ‘Wednesday 15-Jul-2009  7:32 PM’

转载请注明:爱开源 » Linux Socket 学习笔记3–实现一个简单的C/S程序

您必须 登录 才能发表评论!