对于linux下c语言的编程,尤为是网络编程这部分,仍是有一些莫名的爱好的。学习了一些东西,若是不加以总结和实际操做,每每容易忘了。因此,在此写个系列的博客,记录一下,从零开始写linux下的服务器编程。但愿看到这篇日志的同窗,多提意见,共同窗习。 linux
对于网络编程,主要是对socket和IO进行操做。为了实现高效通信,须要一些策略,后面会介绍到。做为开篇,主要是对socket的基础操做的讲解。 git
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,就能够实现服务器与客户端的通信了。 socket