【linux下c语言服务器开发系列】 开篇(socket的基本操作)

天涯浪子 提交于 2019-12-03 01:03:31

    

    对于linux下c语言的编程,尤其是网络编程这部分,还是有一些莫名的爱好的。学习了一些东西,如果不加以总结和实际操作,往往容易忘了。所以,在此写个系列的博客,记录一下,从零开始写linux下的服务器编程。希望看到这篇日志的同学,多提意见,共同学习。

    对于网络编程,主要是对socket和IO进行操作。为了实现高效通讯,需要一些策略,后面会介绍到。作为开篇,主要是对socket的基础操作的讲解。

    socket本质上就是一个int的数字,文件描述符,用于标识主机间端到端的通讯。两端的主机,通过对该socket进行读写,完成双方的通讯。

    socket需要新建(socket())、绑定(bind()),监听(listen),接收连接(accept()),以及读写(read() write(),还有别的IO函数)等。绑定,是将已经新建好的socket与本地的地址进行一个联系。地址( struct sockaddr_in )的设定往往根据需要的具体情况,包括协议、端口、IP地址等。监听是告诉客户端,服务器这边已经准备好了,等待为其服务啦。接受连接是在客户端请求连接时,双方建立连接的通道,为通讯做好准备。接下来,就是数据交换(读和写)。关于读写的函数,比较多,read()\write(), recv()\send()、recvfrom\sendto(),recvmsg()\sendmsg()等。几组函数间比较相似,个别又有特点,接下来会有一篇专门介绍各种读写函数的。

    学习的过程,更多的还是在于动手写。下面先写一个简单的demo,一个回射服务器(就是客户端传来什么内容,服务器就写回给客户端什么内容)。接下来的几个例子,都是在此基础上进行改进的。当然了,后面随着深入,简单的回射服务器可能不能满足我们的要求了,我们会写个http服务器之类的。下面是代码。具体的代码可以见托管处  http://git.oschina.net/mengqingxi89/codelittle/blob/master/codes/echoserver/echoser.cpp。当然了,这个demo是最基本的demo,只能处理一个客户的请求,异常处理什么的也没考虑。不过,接下来,我们会慢慢的优化,不要着急哦。

#include"head.h"
/*因为涉及的头文件比较多,单写了一个头文件,包括引用头文件和全局变量、常用函数的定义等*/

int main(int argc, char **argv)
{
        if(argc<3)
        {
                printf("usage: %s ip port\n",basename(argv[0]));
                exit(0);
        }

        printf("start echoback server...\n");

        char * ip=(char * ) argv[1];
        int port =atoi(argv[2]);


/*构造服务器端的地址,主要是填充sockaddr_in 结构体*/        
        struct sockaddr_in  server_address;
        bzero(&server_address,sizeof(server_address));
        server_address.sin_family=AF_INET;
        inet_pton(AF_INET,ip,&server_address.sin_addr);
        server_address.sin_port=htons(port);

        int listenfd=socket(AF_INET,SOCK_STREAM,0);
        assert(listenfd>=0);
        setnonblock(listenfd);

        int ret=bind(listenfd,(struct sockaddr *) &server_address, sizeof(server_address));
        assert(ret==0);

        ret=listen(listenfd,5);
        assert(ret==0);

/*服务器服务启动,等待客户端的链接的到来*/
        int run_flag=1;
        char buf[1024];
        int conn=-1;
        while(run_flag)
        {

            int acfd=accept(listenfd,NULL,NULL);
/*因为listenfd是非阻塞的,所以,可能返回是小于0的值,此时应该继续处理上一个连接*/
            if(acfd>=0)
                    conn=acfd;

            printf("%d\n",conn);
            bzero(buf,1024);
            int ret=read(conn,buf,1023);
            if(ret>0)
            {
                    buf[ret]=0;
                    printf("received: %s\n",buf);
                    write(conn,buf,ret);
            }
            else if (ret==0)
            {
                    printf("read 0\n");
                    close(conn);
            }
            else
            {
                    printf("read error\n");
                    close(conn);
            }
          
        }
        
}

    在服务器端执行该文件,然后另起一个终端,用telnet连接对应的IP和PORT,就可以实现服务器与客户端的通讯了。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!