6.TCP網(wǎng)絡(luò)創(chuàng)建

1. socket

#include <sys/types.h>
#include <sys/socket.h>
int socket(int domain, int type, int protocol);
功能:創(chuàng)建一個(gè)套接字,返回一個(gè)文件描述符

    參數(shù):
        domain:通信域
            AF_UNIX 本地通信
            AF_INET IPV4網(wǎng)絡(luò)通信
            AF_PACKET 底層通信
        type:socket的類(lèi)型
            SOCK_STREAM 流式套接字 tcp
            SOCK_DGRAM 數(shù)據(jù)報(bào)套接字 UDP
            SOCK_RAW 底層通信
        protocol:協(xié)議,一般為0
    返回值:
        成功:文件描述符
        失?。?1
    例子:
        int sockfd;
        if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        {
            perror("fail to socket");
            //return -1;
            exit(1);
        }

2. bind

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:將套接字與網(wǎng)絡(luò)信息結(jié)構(gòu)體綁定

    參數(shù):
    sockfd:文件描述符,socket的返回值
    addr:網(wǎng)絡(luò)信息結(jié)構(gòu)體
            通用的(一般不用):
                struct sockaddr {
                    sa_family_t sa_family;   2個(gè)字節(jié)
                    char        sa_data[14];  14個(gè)字節(jié)
                }
            一般使用:sockaddr_in
                #include <netinet/in.h>
                struct sockaddr_in
                {
                    __SOCKADDR_COMMON (sin_); 協(xié)議族 AF_INET  2字節(jié)
                    in_port_t sin_port;   端口號(hào)  2個(gè)字節(jié)    
                    struct in_addr sin_addr;   IP地址  4個(gè)字節(jié)
                
                    這個(gè)沒(méi)有用,為了保證與sockaddr大小一致
                    unsigned char sin_zero[sizeof (struct sockaddr) -
                            __SOCKADDR_COMMON_SIZE -
                            sizeof (in_port_t) -
                            sizeof (struct in_addr)];
                };
    addrlen:addr的大小 
    返回值:
        成功:0
        失?。?1
    例子:
        struct sockaddr_in serveraddr;
        serveraddr.sin_family = AF_INET;
        serveraddr.sin_port = htons(9999);
        serveraddr.sin_addr.s_addr = inet_addr("192.168.1.23");
        
        if(bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr_in)) < 0)
        {
            perror("fail to bind");
            exit(1);
        }

3. listen

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int listen(int sockfd, int backlog);
功能:將套接字設(shè)置為監(jiān)聽(tīng)模式

    參數(shù):
        sockfd:文件描述符,socket的返回值
        backlog:允許同時(shí)響應(yīng)連接的客戶端的個(gè)數(shù)
            一般設(shè)置為5 10
    返回值:
        成功:0
        失敗:-1
    例子:
        if(listen(sockfd, 5) < 0)
        {
            perror("fail to listen");
            exit(1);
        }

4. accept

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
功能:阻塞等待客戶端的連接請(qǐng)求

    參數(shù):
        sockfd:文件描述符,socket的返回值
        addr:網(wǎng)絡(luò)信息結(jié)構(gòu)體(自動(dòng)填充的客戶端的網(wǎng)絡(luò)信息結(jié)構(gòu)體)
        addrlen:addr的大小
    返回值:
        成功:返回新的文件描述符(此文件描述符用于通信)
        失敗:-1
    例子:
        int acceptfd;
        struct sockaddr_in clientaddr;
        socklen_t addlen = sizeof(clientaddr);
        if((acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &addlen)) < 0)
        {
            perror("fail to accept");
            exit(1);
        }

5. connect

#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
功能:發(fā)送客戶端的連接請(qǐng)求

    參數(shù):
        sockfd:文件描述符,socket的返回值
        addr:服務(wù)器網(wǎng)絡(luò)信息結(jié)構(gòu)體
        addrlen:addr的大小
    返回值:
        成功:0
        失?。?1

6. send

#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
功能:發(fā)送數(shù)據(jù)

    參數(shù):
        sockfd:文件描述符
            服務(wù)器端:accept的返回值
            客戶端:socket的返回值
        buf:發(fā)送的數(shù)據(jù)
        len:buf 的長(zhǎng)度
        flags:標(biāo)志位
            0 阻塞
            MSG_DONTWAIT 非阻塞
    返回值:
        成功:發(fā)送的數(shù)據(jù)的長(zhǎng)度
        失?。?1

7. recv

#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能:接收數(shù)據(jù)

    參數(shù):
        sockfd:文件描述符
            服務(wù)器端:accept的返回值
            客戶端:socket的返回值
        buf:接收的數(shù)據(jù)
        len:buf 的長(zhǎng)度
        flags:標(biāo)志位
            0 阻塞
            MSG_DONTWAIT 非阻塞
    返回值:
        成功:接收的數(shù)據(jù)的長(zhǎng)度
            0:表示對(duì)方異常退出時(shí),此時(shí)recv返回0
        失?。?1

TCP網(wǎng)絡(luò)編程

#include <stdio.h> //printf
#include <arpa/inet.h> //inet_addr htons
#include <sys/types.h>
#include <sys/socket.h> //scoket bind listen accept connect
#include <netinet/in.h> //sockaddr_in
#include <stdlib.h> //exit
#include <unistd.h> //close
#include <string.h> 

#define N 128
#define errlog(errmsg) do{perror(errmsg);\
                          printf("%s-->%s-->%d\n", __FILE__, __func__, __LINE__);\
                          exit(1);\
                         }while(0)

服務(wù)器端

int main(int argc, const char *argv[])
{
    int sockfd, acceptfd;
    struct sockaddr_in serveraddr, clientaddr;
    socklen_t addrlen = sizeof(serveraddr);
    char buf[N] = {};

    if(argc < 3)
    {
        printf("the argument is too less\n");
        exit(1);
    }

    //第一步:創(chuàng)建套接字
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        errlog("fail to socket");
    }

    //第二步:填充服務(wù)器網(wǎng)絡(luò)信息結(jié)構(gòu)體
    //inet_addr:將點(diǎn)分十進(jìn)制IP地址轉(zhuǎn)化為網(wǎng)絡(luò)字節(jié)序的整型數(shù)據(jù)
    //htons:將主機(jī)字節(jié)序轉(zhuǎn)化為網(wǎng)絡(luò)字節(jié)序
    //atoi:將數(shù)字型字符串轉(zhuǎn)化為整型數(shù)據(jù)
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    serveraddr.sin_port = htons(atoi(argv[2]));

    //第三步:將套接字域網(wǎng)絡(luò)信息結(jié)構(gòu)體綁定
    if(bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
    {
        errlog("fail to bind");
    }

    //第四步:將套接字設(shè)置為監(jiān)聽(tīng)狀態(tài)
    if(listen(sockfd, 5) < 0)
    {
        errlog("fail to listen");
    }


     //第五步:阻塞等待客戶端的連接請(qǐng)求
        if((acceptfd = accept(sockfd, (struct sockaddr *)&clientaddr, &addrlen)) < 0)
    {
        errlog("fail to accept");
    }

    //接收數(shù)據(jù),并打印
    recv(acceptfd, buf, N, 0);
    printf("buf : %s\n", buf);

    close(acceptfd);
    close(sockfd);
    return 0;
}

客戶端

int main(int argc, const char *argv[])
{
    int sockfd;
    struct sockaddr_in serveraddr;
    socklen_t addrlen = sizeof(serveraddr);
    char buf[N] = {};

    if(argc < 3)
    {
        printf("the argument is too less\n");
        exit(1);
    }

    //第一步:創(chuàng)建套接字
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        errlog("fail to socket");
    }

    //第二步:填充服務(wù)器網(wǎng)絡(luò)信息結(jié)構(gòu)體
    //inet_addr:將點(diǎn)分十進(jìn)制IP地址轉(zhuǎn)化為網(wǎng)絡(luò)字節(jié)序的整型數(shù)據(jù)
    //htons:將主機(jī)字節(jié)序轉(zhuǎn)化為網(wǎng)絡(luò)字節(jié)序
    //atoi:將數(shù)字型字符串轉(zhuǎn)化為整型數(shù)據(jù)
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    serveraddr.sin_port = htons(atoi(argv[2]));

    //第三步:向服務(wù)器端發(fā)送連接請(qǐng)求
    if(connect(sockfd, (struct sockaddr *)&serveraddr, addrlen) < 0)
    {
        errlog("fail to connect");
    }

    //從終端輸入,發(fā)送數(shù)據(jù)
    fgets(buf, N, stdin);
    buf[strlen(buf) - 1] = '\0';

    if(send(sockfd, buf, N, 0) < 0)
    {
        errlog("fail to send");
    }

    close(sockfd);
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容