C/C++编程之socket基本函数的用法

2015-01-17 13:40:24|?次阅读|上传:wustguangh【已有?条评论】发表评论

关键词:C/C++, 网络通信|来源:唯设编程网

3.等待监听函数

#include<sys/socket.h>
int listen (int sockfd, int backlog);

返回:

0──成功, -1──失败

参数

sockfd:被listen函数作用的套接字,sockfd之前由socket函数返回。在被socket函数返回的套接字fd之时,它是一个主动连接的套接字,也就是此时系统假设用户会对这个套接字调用connect函数,期待它主动与其它进程连接,然后在服务器编程中,用户希望这个套接字可以接受外来的连接请求,也就是被动等待用户来连接。由于系统默认时认为一个套接字是主动连接的,所以需要通过某种方式来告诉系统,用户进程通过系统调用listen来完成这件事。

backlog:这个参数涉及到一些网络的细节。在进程正理一个一个连接请求的时候,可能还存在其它的连接请求。因为TCP连接是一个过程,所以可能存在一种半连接的状态,有时由于同时尝试连接的用户过多,使得服务器进程无法快速地完成连接请求。如果这个情况出现了,服务器进程希望内核如何处理呢?内核会在自己的进程空间里维护一个队列以跟踪这些完成的连接但服务器进程还没有接手处理或正在进行的连接,这样的一个队列内核不可能让其任意大,所以必须有一个大小的上限。这个backlog告诉内核使用这个数值作为上限。

毫无疑问,服务器进程不能随便指定一个数值,内核有一个许可的范围。这个范围是实现相关的。很难有某种统一,一般这个值会小30以内。

4.接受连接函数

int accept (int sockfd, struct sockaddr *addr, socklen_t *addr_len);

sockfd为服务器上处于监听状态的socket,系统会把远程客户端的信息保存到addr所指向的结构提中,addrlen为sockaddr的内存长度,可以用sizeof获得。

当使用accept接受一个连接时,会返回一个新的sockfd,以后传输通过这个新的sockfd来处理,原来参数中的socket也可以继续使用。如果处理失败返回-1。

程序listen_accept.c中应用了listen和accept函数,代码如下:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#define PORT 2345

int main()
{
    int sockfd, newsockfd;
    struct sockaddr_in addr;
    if( (sockfd=socket(AF_INET,SOCK_STREAM,0)) < 0 )
    {
        perror("socket create error!");
        exit(1);
    }
    else
    {
        printf("socket create successfully!
");
        printf("socket id:%d
",sockfd);
    }

    bzero(&addr,sizeof(struct sockaddr_in));
    addr.sin_family=AF_INET;
    addr.sin_port=htons(PORT);
    //htons,htonl,ntohs,ntohl四个函数用于本地和网络字节序的转换
    //h:host, n:network, s:short, l:long
    //short用uint16_t类型,long用uint32_t类型
    addr.sin_addr.s_addr=htonl(INADDR_ANY);
    if( bind(sockfd,(struct sockaddr*)(&addr), sizeof(struct sockaddr))
        < 0 )
    {
        perror("bind error!");
        exit(2);
    }
    else
    {
        printf("bind port successfully!");
        printf("local port:%d
",PORT);
    }

    const int max_connection = 5;
    if( listen(sockfd,max_connection) < 0 )
    {
        perror("listen error");
        exit(1);
    }
    else
    {
        printf("listenning.....
");
    }

    socklen_t addr_len=sizeof(struct sockaddr_in);
    if( (newsockfd=accept(sockfd,(struct sockaddr*)(&addr),
            &addr_len)) < 0 )
    {
        perror("accpet error!");
    }
    else
    {
        printf("accept a new connection!
");
        printf("new socket id:%d
",newsockfd);
    }
    return 0;
}

运行结果如下:

socket create successfully!
socket id:3
bind port successfully!local port:2345
listenning.....

程序运行到这里后停止了,在浏览器地址栏中输入:

http://127.0.0.1:2345/

然后按回车,结果如下:

accept a new connection!
new socket id:4

可以看到建立了新的套接口,编号为4。

发表评论0条 】
网友评论(共?条评论)..
C/C++编程之socket基本函数的用法