linux c socket編程回顧二:簡單服務端、客戶端

通過上篇的講解,我們可以寫一個簡單的服務端、客戶端:

這裏仍有一些可圈點之處:

  1. INADDR_ANY,轉換過來就是0.0.0.0,是指本機所有ip,比如本機有多個網卡多個ip,只需綁定某個ip的地址,
    只能監聽某個網卡過來的消息,這裏INADDR_ANY,監聽所有網卡的消息。
  2. inet_addr()將一個字符串類型的ip地址比如“192.168.0.100”轉化爲uint32_t數字格式,因爲網絡傳輸地址用的是uint32_t格式
  3. socket默認是阻塞的,阻塞的地方有:連接、收、發,其中連接有個系統超時時間,這個時間通常會很長,如果是我們一次發送大量的連接請求,一個阻塞後,後續的就一直等待,顯然是不合理的,所以我們一般會修改這個超時連接時間;對於收、發(即讀、寫),若是沒有數據到來則會一直阻塞,根據需求有時需要我們做一個非阻塞處理,在一定時間沒有數據到來時仍會返回。關於阻塞、非阻塞下篇講解。
#include <sys/socket.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

#define PORT 10102

int main()
{
        int sockfd;
        int client_fd;
        //socket
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if( sockfd < 0 )
        {
                perror("socket error!");
                return -1;
        }

        //bind
        struct sockaddr_in client_addr, server_addr;
        memset(&server_addr, 0x00, sizeof(struct sockaddr_in));
        server_addr.sin_family=AF_INET;                 //協議
        server_addr.sin_addr.s_addr=INADDR_ANY;         //服務器地址--允許鏈接到本地任何地址
        server_addr.sin_port=htons(PORT);

        if(bind(sockfd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)) < 0)
        {
                perror("bind error!");
                return -1;

        }

        //listen
        listen(sockfd, 5); //5也是系統的默認值
        printf("start listen......\n");

        //accept 接收客戶端收鏈接
        int size = sizeof(struct sockaddr_in);
        if( (client_fd = accept(sockfd, (struct sockaddr *)&client_addr, &size)) < 0)
        {
                perror("accept error!");
                return -1;

        }
        printf("accept client %s\n",inet_ntoa(client_addr.sin_addr));
        send(client_fd, "welcome\n", 8, 0);
        //recv/send
        int n;
        char buf[1024]={0};
        while((n = recv(client_fd, buf, 1024, 0)) > 0)
        {
                buf[n] = '\0';
                printf("%s\n", buf);
                if(send(client_fd, buf, n, 0) < 0)
                {
                        perror("error send!");
                        return -1;
                }

        }
        close(client_fd);
        close(sockfd);

        return 0;
}

簡單的客戶端

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

#define PORT 10102

int main()
{
        int sockfd;
        int client_fd;
        //socket
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if( sockfd < 0 )
        {
                perror("socket error!");
                return -1;
        }

        struct sockaddr_in server_addr;
        memset(&server_addr, 0x00, sizeof(struct sockaddr_in));
        server_addr.sin_family=AF_INET;                 //協議
        server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");             //服務器地址
        server_addr.sin_port=htons(PORT);

        //connect
        if(connect(sockfd, (struct sockaddr*)&server_addr, sizeof(struct sockaddr)) < 0)
        {
                perror("connect error!");
                return -1;

        }

        //recv/send
        char buf[1024]={0};

        printf("connected to server\n");
        recv(sockfd, buf, 1024, 0);
        printf("%s\n",buf);

        int n;
        while(1)
        {
                memset(buf, 0x00, sizeof(buf));
                printf("Enter string to send:");
                scanf("%s",buf);
                if(strncmp(buf,"quit", 4) == 0)
                        break;
                n = send(sockfd, buf, strlen(buf), 0);
                n = recv(sockfd, buf, 1024,0);
                buf[n]='\0';
                printf("recv:[%s]\n", buf);


        }
        close(sockfd);

        return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章