linux下socket编程归纳记录

所需头文件:

#include<sys/types.h>
#include<sys/socket.h>

基础套接字:

返回值:
    0表示成功
    -1表示失败
    errno记录错误代码
1:创建套接字
    int socket(int domain, int type, int protocol)
    参数描述:
    domain:套接字域名
    {
        AF_UNIX:用于本地通信
        AF_INET:IPv4,Internet协议(本例使用该域名做参考)
        AF_INET6:IPv6,Internet协议
        .
        .
     }
     type:套接字类型
     {
        SOCK_STREAM:流式套接字,用于套接字之间流式I/O操作,需先建立连接。特点1是数据按照写入时顺序被读取方接收,保证传输正确性,因此提供可靠的数据传输;特点2是仅仅是简单将数据交给接收方。
        SOCK_DGRAM:数据报套接字,用与无连接通信。数据传输并不严格,接收端不能知道是否丢失了数据。
      }
     protocaol:使用的协议
     {
         一般情况下为0,系统会自动选择适合的协议类型。
      }
 2:请求连接函数:

int connect(int sockfd, const struct sockaddr *servaddr,socklen_t addrlen)
    参数描述:
    sockfd:sokect生成的套接字
    servaddr:客户端准备连接的服务器地址
    addrlen:服务器地址的长度

3:绑定本地地址函数:
int bindint sockfd,const struct sockaddr *myaddr,socklen_t addrlen)
    参数描述:
    sockfd:sokect生成的套接字
    myaddr:分配给套接字sockfd的地址指针
    addrlen:myaddr地址的长度
4:监听函数:
int listenint sockfd,int backlog)
    参数描述:
    sockfd:sokect生成的套接字
    backlog:指完成TCP三次握手后已成功建立的TCP连接的队列长度,服务器执行accept操作从该队列中取下一个连接进行后续处理。
    ![backlog队列管理](http://img.blog.csdn.net/20150603105753422)
接收请求函数:
int acceptint sockfd, struct sockaddr *cliaddr,socklen_t *addrlen)
    参数描述:
    sockfd:sokect生成的套接字
    cliaddr:用于接收客户端套接字地址的地址结构指针
    addrlen:用于接收的套接字地址换岑最大长度的指针
    返回值:
    如果调用成功,将是一个新的套接字描述符,称为连接套接字,服务器使用该套接字和已建立连接的客户端进行通信,而原有的监听套接字继续接收后续新客户端发来的连接请求。连接套接字在通信完毕后通常会被立刻关闭,但是监听套接字一直处于监听状态直达应用结束。

例子
客户端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


int main(void)
{

        int st = socket(AF_INET, SOCK_STREAM, 0);//初始化socket,

        struct sockaddr_in addr;//定义一个IP地址的结构
        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;//设置结构地址类型为TCP/IP地址
        addr.sin_port = htons(8080);//指定一个端口号:8080,htons:将short类型从host字节类型到net字节类型转化
        addr.sin_addr.s_addr = inet_addr("192.168.182.128");//将字符串类型的IP地址转化为int,赋给addr结构成员.

        //调用connect连接到结构addr指定的IP地址和端口号
        if (connect(st, (struct sockaddr *) &addr, sizeof(addr)) == -1)
        {
                printf("connect failed %s\n", strerror(errno));
                return EXIT_FAILURE;
        }

        char s[1024];
        memset(s, 0, sizeof(1024));
        strcpy(s, "hello world");
        if (send(st, s, strlen(s), 0) == -1)//发送buf的数据
        {
                printf("send failed %s\n", strerror(errno));
                return EXIT_FAILURE;
        }

        close(st);//关闭socket
        return EXIT_SUCCESS;

}

服务器端:

#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


int main(int arg, char *args[])
{
        int st = socket(AF_INET, SOCK_STREAM, 0);//初始化socket

        int on = 1;
        if (setsockopt(st, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1)
        {
                printf("setsockopt failed %s\n", strerror(errno));
                return EXIT_FAILURE;
        }


        struct sockaddr_in addr;//定义一个IP地址结构
        memset(&addr, 0, sizeof(addr));
        addr.sin_family = AF_INET;//将addr结构的属性定位为TCP/IP地址
        addr.sin_port = htons(8080);//将本地字节顺序转化为网络字节顺序。
        addr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY代表这个server上所有的地址

        //将IP与server程序绑定
        if (bind(st, (struct sockaddr *) &addr, sizeof(addr)) == -1)
        {
                printf("bind failed %s\n", strerror(errno));
                return EXIT_FAILURE;
        }

        //server端开始listen,
        if (listen(st, 20) == -1)
        {
                printf("listen failed %s\n", strerror(errno));
                return EXIT_FAILURE;
        }
        char s[1024];
        int client_st = 0;//client端socket
        //socklen_t len = 0;
        struct sockaddr_in client_addr;//表示client端的IP地址
        //void *p = &client_addr;
        int i;
        for (i = 0; i < 5; i++)
        {
                memset(&client_addr, 0, sizeof(client_addr));
                socklen_t len = sizeof(client_addr);
                //accept会阻塞,直到有客户端连接过来,accept返回client的socket描述符
                client_st = accept(st, (struct sockaddr *)&client_addr , &len);
                if (client_st == -1)
                {
                        printf("accept failed %s\n", strerror(errno));
                        return EXIT_FAILURE;
                }
                while(1)
                {
                        memset(s, 0, sizeof(1024));
                        int rc = recv(client_st, s, sizeof(s), 0);//recv是阻塞调用,
                        if (rc > 0)//接收来自client的消息
                        {
                                printf("revc is %s\n", s);
                        }else
                        {
                                if (rc == 0)
                                {
                                        printf("client socket closed\n");
                                }else
                                        printf("recv failed %s\n", strerror(errno));
                                break;
                        }
                }
                close(client_st);//关闭client端socket
        }
        close(st);//关闭server端listen的socket
        return EXIT_SUCCESS;
}

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。