TCP-based c/s primary network programming 1

Source: Internet
Author: User
Guide

This article introduces the "Calculator" of the C/S architecture.

After reading network programming, I am not conscious of YY: to implement a simple calculator, the client provides a simple operation, and the server is responsible for the operation. This small project is very interesting and difficult to do, so it is recommended that beginners try to do it. The following describes how to implement the "Calculator.

Simple TCP-based c/s programming is inseparable from these functions:

Server: socket, bind, listen, accept, Recv, send
Client: socket, connect, Recv, send

 

Because the "Calculator" is also designed to block the client (because the client may wait for the server to return the computing result after submitting the operation requirements, the client is required to block the wait), so the select function is involved. The select function is widely used and can easily implement blocking. Introduction to a document, interested can refer to: http://wenku.baidu.com/view/0ea86ffdc8d376eeaeaa3198.html

Objective test environment

You can test both the server and the client on a host, as long as the customer uses the loopback address (or local static IP address) to connect to the server during connect.

Implementation Details

What if socket fails, BIND fails, and listen fails... there are corresponding error handling, and this kind of habit of "taking into account weekly details" (taking into account all situations, such as printing error information when an error occurs) is very helpful for debugging.

Http://www.gnu.org/software/libc/manual/html_node/Internet-Address-Formats.html

-Data Type:Struct sockaddr_in

This is the data type used to represent socket addresses in the Internet namespace. It has the following members:

sa_family_t sin_family
This identifies the address family or format of the socket address. You shocould store the value AF_INETIn this member. See socket addresses.
struct in_addr sin_addr
This is the Internet address of the host machine. See host addresses, and host names, for how to get a value to store here.
unsigned short int sin_port
This is the port number. See ports.

Note: sockaddr_in this type of data must be bzero before use

Sin_addr is the struct,

Http://www.gnu.org/software/libc/manual/html_node/Host-Address-Data-Type.html

-Data Type:Struct in_addr

This data type is used in certain contexts to contain an IPv4 internet host address. It has just one field, nameds_addr, Which records the host address number asuint32_t.

Inet_ton and iNet-_ ntop can be easily converted into a decimal IP address string and uint32_t (the IP address is 4 bytes and should be in the network byte order.

Select

As stated above, "after the client submits the operation requirements, the server may have to wait for the result to be sent back. In this case, the client is required to block the wait." select is often used as a blocking role.
Http://www.gnu.org/software/libc/manual/html_node/Waiting-for-I_002fO.html (detailed documentation)
Therefore, after the client submits an operation request, it must block its socket READ function until there is data (that is, the result returned by the server. If the round-robin method is used, CPU is a waste.

Solution

Server startup

The client was started. It was too fast and the results all came out.

Server processing is complete, quit

Calculator requirements: the customer needs to pass the suffix expression for simple operations (such as), the server can directly run.
Defect: This calculator serves only one customer and is not processed by others. Further improvements to this calculator can be made to accept requests from more than one customer.

Client

#include <stdio.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/ip.h>#include <arpa/inet.h>#include <string.h>#include <string.h>#define MAXSLEEP 1024int connect_retry(int sockfd,const struct sockaddr * addr,socklen_t alen){    int nsec;    printf("connecting\n");    for(nsec = 1; nsec <= MAXSLEEP; nsec<<=1)    {        if(connect(sockfd,addr,alen) == 0)        {            printf("connected\n");            return 0;        }// if        if(nsec <= MAXSLEEP/2)//    delay            sleep(nsec);    }// for:    return 0;}int main(int argc,char * argv[]){    if(argc != 4)    {        printf("you must input 4 arg\n");        return 1;    }// if    int fd;        struct sockaddr_in si,server;    char addr[20],buf[20],bufrecv[20];    bzero(bufrecv,sizeof(bufrecv));    sprintf(addr,"127.0.0.1");        fd = socket(AF_INET,SOCK_STREAM,0);//   create socker fd;    printf("socket ok\n");//prepare server addr    bzero(&server,sizeof(server));    server.sin_family = AF_INET;    server.sin_port = htons(6000);    inet_pton(AF_INET,addr,(void *)&server.sin_addr);    printf("server ok\n");//prepare request data    bzero(buf,sizeof(buf));    sprintf(buf,"%c%c%c",argv[1][0],argv[2][0],argv[3][0]);//connect    if(connect_retry(fd,(struct sockaddr *)&server,sizeof(server)) < 0)    {        printf("connect error\n");        return 1;    }// if//send    if(send(fd,buf,20,0) < 0)     {        printf("client send error\n");        return 1;    }// if//select    fd_set readfd;    FD_ZERO(&readfd);    FD_SET(fd,&readfd);    int t;    if((t = select(FD_SETSIZE,&readfd,NULL,NULL,NULL)) < 0)    {        printf("select error\n");        return 1;    }// if//recv    bzero(bufrecv,sizeof(bufrecv));    recv(fd,bufrecv,20,0);    printf("%s\n",bufrecv);    close(fd);    return 0;}

Server

#include <stdio.h>#include <sys/socket.h>#include <netinet/in.h>#include <errno.h>#include <ctype.h>#include <arpa/inet.h>#include <unistd.h>#include <string.h>char bufret[20];int initserver(int type,const struct sockaddr * addr,socklen_t alen,int qlen){    int fd;    int err = 0;    if((fd = socket(addr->sa_family,type,0)) < 0)        return -1;    printf("binding\n");    if(bind(fd,addr,alen) < 0)    {        err = errno;        goto errout;    }// if    printf("bind succeed \n");    if(type == SOCK_STREAM || type == SOCK_SEQPACKET)    {        printf("listening\n");        if(listen(fd,1) < 0)        {            err = errno;            printf("listen error\n");            goto errout;        }// if    }// if    printf("listened \n");    return (fd);errout:    close(fd);    errno = err;    return -1;}int serve(int sockfd){    int a,b;    char op,buf[25];    int ret,addrlen = sizeof(struct sockaddr_in),clfd;     struct sockaddr_in client;    bzero(&client,sizeof(client));//accept       printf("accepting\n");    clfd = accept(sockfd,(struct sockaddr *)&client,&addrlen);//recv    printf("accepted\n");    bzero(buf,sizeof(buf));    recv(clfd,buf,20,0);    printf("recived\n");    //calculate    a = buf[0] - '0';    b = buf[1] - '0';    op = buf[2];    switch(op)    {        case '+':ret = a + b;break;        case '-':ret = a - b;break;        case '*':ret = a * b;break;        case '/':ret = a / b;break;    }// switch    sprintf(bufret,"the result:%d",ret);//send    printf("sending\n");    if(send(clfd,bufret,20,0) < 0)    {        printf("server send error\n");        return -1;    }// if    printf("sended,server end\n");    return 0;}int main(int argc,char * argv[]){    int sockfd;    char addr[20];    bzero(addr,sizeof(addr));    sprintf(addr,"127.0.0.1");    struct sockaddr_in server;    bzero(&server,sizeof(server));    server.sin_family = AF_INET;    server.sin_port = htons(6000);    //server.sin_addr.s_addr = htonl(INADDR_ANY);    inet_pton(AF_INET,addr,(void *)&server.sin_addr);    //prepare server    if((sockfd = initserver(SOCK_STREAM,(struct sockaddr *)&server,sizeof(server),1)) < 0)    {        printf("initserver error\n");        return 0;    }// if        printf("serving\n");//serve    serve(sockfd);    close(sockfd);    return 0;}

The above is my work after YY, and there are still many defects and deficiencies. I will share it with my friends. You are welcome to propose creative suggestions. In addition, if there is any error, you are welcome to make an axe.

End of this article 2012-08-02

Spoof http://www.daoluan.net/

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.