socket 基礎編程 UDP 協議 TCP 協議 socket 編程流程圖 bind listen accept connect send recv sendto recvfrom

                                          粉絲不過W 

socket 基礎編程

    函數說明

       socket: 建立一個 socket 連接,可指定 socket 類型等信息。在建立 socket連接之後,可對 socketadd 或 sockaddr_in 進行初始化,以保存所建立的 socket 信息

       bind:把本地 IP 地址綁定端口號的,若綁定其他地址則不能成功。它主要用於 TCP 的連接,而在 UDP 的連接中則無必要

      connect: TCP :用於 bind 的之後的 client 端,用於與服務器端建立連接,而 UDP 由於沒有 bind 函數,因此用 connect 類似 bind 函數的作用

      send 和 recv:用於接收和發送數據,可用到 TCP ,也可用到 UDP中。當用到 UDP 時,可在 connect 函數建立連接之後再用

      sendto 和 recvfrom:作用與 send 和 recv 函數類型,也可以用在 TCP 和UDP 中。 TCP 時,後面的幾個與地址有關參數不起作用,函數作用等同於 send 和 recv。 UDP 時,可用在沒有使用 connect 之前,可 自動尋找制定地址並進行連接

   TCP 協議 socket 編程流程圖:

UDP 協議 socket 編程流程圖

socket 

#include <sys/socket.h>

/*
 *parameter:
 *  family:
 *    AF_INET: IPv4 協議
 *    AF_INET6:IPv6 協議
 *    AF_LOCAL:UNIX 域協議
 *    AF_ROUTE:路由套接字(socket)
 *    AF_KEY:  密鑰套接字(socket)
 *  type:
 *    SOCK_STREAM: 字節流套接字 socket
 *    SOCK_DGRAM:  數據報套接字 socket
 *    SOCK_RAW:    原始套接字 socket
 *  protoco:0 (原始套接字除外)
 *return:
 *  成功:非負套接字描述符
 *  失敗:-1
 */
int socket(int family, int type, int protocol)

bind 

#include <sys/socket.h>

/*
 *parameter:
 *  socktd:套接字描述符
 *  my_addr:本地地址
 *  addrlen:地址長度
 *return:
 *  成功:0
 *  出錯:-1
 */
int bind(int sockfd, struct sockaddr *my_addr, int addrlen)

listen 

#include <sys/socket.h>

/*
 *parameter:
 *  socktd:套接字描述符
 *  backlog:請求隊列中允許的最大請求數,大多數系統缺省值爲 20
 *return:
 *  成功:0
 *  出錯:-1
 */
int listen(int sockfd,int backlog)

 accept

#include <sys/socket.h>

/*
 *parameter:
 *  socktd:套接字描述符
 *  addr:客戶端地址
 *  addrlen:地址長度
 *return:
 *  成功:0
 *  出錯:-1
 */
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)

connect

#include <sys/socket.h>

/*
 *parameter:
 *  socktd:   套接字描述符
 *  serv_addr:服務器端地址
 *  addrlen:   地址長度
 *return:
 *  成功:0
 *  失敗:-1
 */
int connect(int sockfd, struct sockaddr *serv_addr, int addrlen)

send

#include <sys/socket.h>

/*
 *parameter:
 *  socktd:套接字描述符
 *  msg:指向要發送數據的指針
 *  len:數據長度
 *  flags:一般爲 0
 *return:
 *  成功:發送的字節數
 *  出錯:-1
 */
int send(int sockfd, const void *msg, int len, int flags)

recv

#include <sys/socket.h>

/*
 *parameter:
 *  socktd:套接字描述符
 *  buf:存放接收數據的緩衝區
 *  len:數據長度
 *  flags:一般爲 0
 *return:
 *  成功:接收的字節數
 *  出錯:-1
 */
int recv(int sockfd,void *buf,int len,unsigned int flags)

sendto

#include <sys/socket.h>

/*
 *parameter:
 *  socktd:套接字描述符
 *  msg:指向要發送數據的指針
 *  len:數據長度
 *  flags:一般爲 0
 *  to:目地機的 IP 地址和端口號信息
 *  tolen:地址長度
 *return:
 *  成功:發送的字節數
 *  出錯:-1
 */
int sendto(int sockfd, 
           const void *msg,
           int len,
           unsigned int flags,
           const struct sockaddr *to, 
           int tolen)

recvfrom

#include <sys/socket.h>

/* 
 *parameter:
 *  socktd:套接字描述符
 *  buf:存放接收數據的緩衝區
 *  len:數據長度
 *  flags:一般爲 0
 *  from:源機的 IP 地址和端口號信息
 *  tolen:地址長度
 *return:
 *  成功:接收的字節數
 *  出錯:-1
 */
int recvfrom(int sockfd,
             void *buf,
             int len,
             unsigned int flags,
             struct sockaddr *from,
             int *fromlen)

服務器端

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

#define    SERVPORT    3333
#define    BACKLOG    10
#define    MAX_CONNECTED_NO   10
#define    MAXDATASIZE    5

int main()
{
    struct sockaddr_in server_sockaddr, client_sockaddr;
    int sin_size, recvbytes;
    int sockfd, client_fd;
    char buf[MAXDATASIZE];

    /* 建立 socket 連接 */
    if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
    {
        perror("socket");
        exit(1);
    }
    printf("socket success!,sockfd=%d\n",sockfd);

    /* 設置 sockaddr_in 結構體中相關參數 */
    server_sockaddr.sin_family = AF_INET;
    server_sockaddr.sin_port = htons(SERVPORT);
    server_sockaddr.sin_addr.s_addr = INADDR_ANY;

    /* 綁定函數 bind */
    bzero(&(server_sockaddr.sin_zero), 8);
    if(bind(sockfd, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr)) == -1)
    {
        perror("bind");
        exit(1);
    }
    printf("bind success!\n");

    /*調用 listen 函數*/
    if(listen(sockfd,BACKLOG) == -1)
    {
        perror("listen");
        exit(1);
    }
    printf("listening....\n");

    /*調用 accept 函數,等待客戶端的連接*/
    if((client_fd = accept(sockfd, (struct sockaddr *)&client_sockaddr, &sin_size)) == -1)
    {
        perror("accept");
        exit(1);
    }

    /*調用 recv 函數接收客戶端的請求*/
    if((recvbytes = recv(client_fd, buf, MAXDATASIZE, 0)) == -1)
    {
        perror("recv");
        exit(1);
    }

    printf("received a connection :%s\n",buf);
    close(sockfd);
}

 客戶端

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

#define    SERVPORT    3333
#define    MAXDATASIZE    100

int main(int argc, char *argv[])
{
    int sockfd, sendbytes;
    char buf[MAXDATASIZE];
    struct hostent *host;
    struct sockaddr_in serv_addr;
    
    if(argc < 2)
    {
        fprintf(stderr,"Please enter the server's hostname!\n");
        exit(1);
    }

    /* 地址解析函數 */
    if((host = gethostbyname(argv[1])) == NULL)
    {
        perror("gethostbyname");
        exit(1);
    }

    /* 創建 socket */
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror("socket");
        exit(1);
    }

    /* 設置 sockaddr_in 結構體中相關參數 */
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(SERVPORT);
    serv_addr.sin_addr = *((struct in_addr *)host->h_addr);
    bzero(&(serv_addr.sin_zero),8);

    /* 調用 connect 函數主動發起對服務器端的連接 */
    if(connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1)
    {
        perror("connect");
        exit(1);
    }

    /* 發送消息給服務器端 */
    if((sendbytes = send(sockfd, "hello", 5, 0)) == -1)
    {
        perror("send");
        exit(1);
    }

    close(sockfd);
}

 

生成結果

 

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