基本过程:
服务器首先启动,通过调用socket函数建立一个套接字,然后调用bind将该套接字和本地网络联系在一起,然后调用listen函数将使套接字做好侦听准备,并规定它的请求队列的长度,之后通过调用accept函数接收连接,并且把服务器当前的时间发送给请求的客户端。
下面是这个小Demo的具体代码实现,上面描述的太过于简略,看了之后还是不能很清楚的了解的可以参见下面的代码里面的注释,一点点加的,很详细的~
与之对应的客户端代码实现:http://blog.csdn.net/smarteryu/article/details/8654628
#include<time.h>
#include<stdio.h>
#include<stdlib.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#define LISTENQ 5
#define MAXLINE 512
int main()
{
int listenfd,connfd;//定义了两个套接字描述符变量
socklen_t len;
struct sockaddr_in servaddr,cliaddr;//定义了两个地址结构类型变量
char buff[MAXLINE];
time_t ticks;
//调用socket函数创建了一个流套接字
listenfd=socket(AF_INET,SOCK_STREAM,0);//使用Internet协议族,流套接字,流套接字对应的默认协议(TCP)
//socket(协议族,套接字类型,使用哪种协议),返回值为一个套接字描述符
if(listenfd<0)
{
printf("Socket created failed.\n");
return -1;
}
servaddr.sin_family=AF_INET;//套接字协议族地址类型(TCP/IP类型)
servaddr.sin_port=htons(6666);//套接字地址结构端口号
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);//套接字地址结构IP地址,整数类型引用(INADDR_ANY:愿意接受来自任何网络设备接口的客户机连接)
//调用bind函数将本地地址与套接字绑定在一起
if(bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr))<0)
//bind(套接字描述符,本地地址,套接字地址结构的长度)
{
printf("bind failed.\n");
return -1;
}
printf("listening...\n");
//将一个套接字转换成倾听套接字
listen(listenfd,LISTENQ);
//listen(要转换的套接字描述符,请求队列的最大长度)
while(1)
{
len=sizeof(cliaddr);
//从倾听套接字的完成连接队列中接收一个连接
connfd=accept(listenfd,(struct sockaddr *)&cliaddr,&len);
//accept(指定套接字描述符,指向一个Internet套接字地址结构的指针,指向一个整型变量的指针)
//执行成功函数返回一个新的套接字描述符
//参数cliaddr存储了客户机的地址
//参数len存储了客户机地址的长度
printf("connect from %s,port %d\n",inet_ntoa(cliaddr.sin_addr.s_addr),ntohs(cliaddr.sin_port));
//inet_ntoa:将32位二进制形式IP地址转换为数字点形式的IP地址
//ntohs:将网络字节顺序转化为主机字节顺序
ticks=time(NULL);
sprintf(buff,"%.24s\r\n",ctime(&ticks));
write(connfd,buff,strlen(buff));
//write(套接字描述符,写缓冲区,缓冲区大小)
//关闭返回的客户端套接字描述符
close(connfd);
}
return 0;
}