伯克利SocketAPI(一) socket的C语言接口/最简单的服务器和对应的客户端C语言实现

1. 头文件

2. API函数

 

3. 最简单的服务器和对应的客户端C语言实现

3.1 server

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


int main(int argc, char** argv)
{
    char hello[] = "hello world";
    struct sockaddr_in sa;
    
    int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (-1 == SocketFD)
    {
        perror("cannot create socket");   //鎵撳嵃浠€涔堝師鍥犲嚭閿?
        exit(EXIT_FAILURE);               // 1
    }
    

    memset(&sa, 0, sizeof(sa));

    //c鐨勪範鎯? 鏄剧ず鍒濆�鍖?
    //瀹氫箟浜唅p鍦板潃鍜岀�鍙e彿
    sa.sin_family = AF_INET;
    sa.sin_port = htons(2222); //htons鎶婃搷浣滅郴缁熺殑瀛楄妭搴忥紝杞�寲涓虹綉缁滅殑瀛楄妭搴?==> Linux涓婂皬绔?->澶х�
    sa.sin_addr.s_addr = htonl(INADDR_ANY);
    
    
    //缁戝畾绔�彛鍙?
    //澶辫触: 宸茬粡缁戝畾锛屾垨鑰呭皬浜?024鐨勭�鍙?闇€瑕佹潈闄?
    if (-1 == bind(SocketFD, (struct sockaddr*)&sa, sizeof(sa)))
    {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }

    
    //鐩戝惉, 10:鍚庨潰鍐嶈�
    if (-1 == listen(SocketFD, 10))
    {
        perror("accept failed
");
        close(SocketFD);
        exit(EXIT_FAILURE);
    }


    //鏈嶅姟鍣ㄥ紑濮嬪伐浣? accept:鎺ユ敹涓€娆′笁娆℃彙鎵嬫垚鍔熺殑瀹㈡埛绔�繛鎺?
    for (;;)
    {
        int ConnectFD = accept(SocketFD, NULL, NULL);

        if (0 > ConnectFD)
        {
            perror("accept failed");
            exit(EXIT_FAILURE);
        }
        
        int writeSize = 0;
        size_t totalWrite = 0;
        while (totalWrite < sizeof(hello))
        {
            writeSize = write(ConnectFD, hello + totalWrite, sizeof(hello) - totalWrite);
            if (-1 == writeSize) 
            {
                perror("write failed");
                close(ConnectFD);
                close(SocketFD);
                exit(EXIT_FAILURE);
            }
            totalWrite += writeSize;
        }

        
        if (-1 == shutdown(ConnectFD, SHUT_RDWR))
        {
            perror("shutdown failed
");
            close(ConnectFD);
            close(SocketFD);
            exit(EXIT_FAILURE);
        }
    
        close(ConnectFD);

    }
    
    close(SocketFD);

    return EXIT_SUCCESS;

}

3.2 client

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

int main(int argc, char *argv[])
{
    struct sockaddr_in sa;
    int res;
    //tcp
    int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

    //资源不够
    if (-1 == SocketFD)
    {
        perror("cannot create socket");
        exit(EXIT_FAILURE);
    }

    //初始化sa
    memset(&sa, 0, sizeof(sa));


    //设置连接服务器的 ip和端口号
    sa.sin_family = AF_INET;
    //端口号2222, htons把操作系统的字节序,转化为网络的字节序 
    sa.sin_port = htons(2222);
    //连接本地ip地址
    res = inet_pton(AF_INET, "127.0.0.1", &sa.sin_addr);

    //客户端,设置连接服务器 
    //失败,则释放资源
    if (-1 == connect(SocketFD, (struct sockaddr*)&sa, sizeof(sa)))
    {
        perror("connect failed
");
        close(SocketFD);
        exit(EXIT_FAILURE);
    }

    char buffer[512];
    int totalRead = 0;
    for (;;)
    {
        int readSize = 0;
        readSize = read(SocketFD, buffer + totalRead, sizeof(buffer) - totalRead);
        if (readSize == 0)
        {
            //read all 
            break;
        }
        else if (readSize == -1)
        {
            perror("read failed");
            close(SocketFD);
            exit(EXIT_FAILURE);
        }

    char buffer[512];
    int totalRead = 0;
    for (;;)
    {
        int readSize = 0;
        readSize = read(SocketFD, buffer + totalRead, sizeof(buffer) - totalRead);
        if (readSize == 0)
        {
            //read all 
            break;
        }
        else if (readSize == -1)
        {
            perror("read failed");
            close(SocketFD);
            exit(EXIT_FAILURE);
        }

        totalRead += readSize;
    }

    buffer[totalRead] = 0;
    printf("get from server: %s
", buffer);
    /* perform read wirte operations ...*/

    (void)shutdown(SocketFD, SHUT_RDWR);

    close(SocketFD);

    return EXIT_SUCCESS;

} 

 当服务器主动关闭连接的时候,会出现 TIME_WAIT状态(哪一边主动关闭连接,TIME_WAIT发生在哪一边)

 

原文地址:https://www.cnblogs.com/douzujun/p/10645385.html