日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

socket通信之最简单的socket通信

發布時間:2023/11/30 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 socket通信之最简单的socket通信 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

http://blog.csdn.net/xluren/article/details/8043484#t15

套接字有三種類型

流式套接字(SOCK_STREAM),數據報套接字(SOCK_DGRAM)及原始套接字。

1.流式套接字提供面向連接、可靠的數據傳輸服務,數據按字節流、按順序收發,保證在傳輸過程中無丟失、無冗余。TCP協議支持該套接字。

2.數據報套接字,提供面向無連接的服務,數據收發無序,不能保證數據的準確到達。UDP協議支持該套接字。

3.原始套接字原始套接字主要用于一些協議的開發,可以進行比較底層的操作。它功能強大,但是沒有上面介紹的兩種套接字使用方便,一般的程序也涉及不到原始套接字。

重要的幾個結構體:

1.sockaddr

[cpp]?view plain?copy
  • struct?sockaddr??
  • {??
  • ????????unsigned?short?sa_family;?/*?address族,?AF_xxx?*/??
  • ????????char?sa_data[14];?/*?14?bytes的協議地址?*/??
  • };??
  • sa_family 一般來說,都是“AFINET”。
    sa_data 包含了一些遠程電腦的地址、端口和套接字的數目,它里面的數據是雜溶在一切的。

    由于在設置上面比較麻煩,所以有了一個更清晰的結構體數據

    2.struct sockaddr_in

    注:“in” 代表 “Internet”

    [cpp]?view plain?copy
  • struct?sockaddr_in???
  • {??
  • ????????short?int?sin_family;?/*?Internet地址族?*/??
  • ????????unsigned?short?int?sin_port;?/*?端口號?*/??
  • ????????struct?in_addr?sin_addr;?/*?Internet地址?*/??
  • ????????unsigned?char?sin_zero[8];?/*?添0(和struct?sockaddr一樣大小)*/??
  • };??
  • 3.struct in_addr (Internet地址)

    struct in_addr
    {
    ?unsigned long s_addr;
    };

    一些函數:

    1.socket

    #include <sys/types.h>
    #include <sys/socket.h>
    int socket(int domain , int type , int protocol);

    說明:

    domain 需要被設置為“AF_INET”;

    type為套接字類型;

    protocol為協議一般設置為0

    2.bind()

    #include <sys/types.h>
    #include <sys/socket.h>
    int bind (int sockfd , struct sockaddr *my_addr , int addrlen) ;
    參數說明:
    sockfd 是由socket()函數返回的套接字描述符。
    my_addr 是一個指向struct sockaddr 的指針,包含有關你的地址的信息:名稱、端口和IP 地址,可以將struct sockaddr_in結構體強制類型轉換傳入。
    addrlen 可以設置為sizeof(struct sockaddr)。

    3.connect()

    #include <sys/types.h>
    #include <sys/socket.h>
    int connect (int sockfd, struct sockaddr *serv_addr, int addrlen);
    參數說明:

    sockfd :套接字文件描述符,由socket()函數返回的。
    serv_addr 是一個存儲遠程計算機的IP 地址和端口信息的結構。
    addrlen 應該是sizeof(struct sockaddr)。

    4.listen()

    #include <sys/socket.h>
    int listen(int sockfd, int backlog);
    參數說明:

    sockfd 是一個套接字描述符,由socket()系統調用獲得。
    backlog 是未經過處理的連接請求隊列可以容納的最大數目。

    5.accept()

    #include <sys/socket.h>
    int accept(int sockfd, void *addr, int *addrlen);
    參數說明:

    sockfd 是正在listen() 的一個套接字描述符。
    addr 一般是一個指向struct sockaddr_in 結構的指針;里面存儲著遠程連接過來的計算機的信息(比如遠程計算機的IP 地址和端口)。
    addrlen 是一個本地的整型數值,在它的地址傳給accept() 前它的值應該是sizeof(struct sockaddr_in);accept()不會在addr 中存儲多余addrlen bytes 大小的數據。如果accept()函數在addr 中存儲的數據量不足addrlen,則accept()函數會改變addrlen 的值來反應這個情況。

    注:調用成功后返回一個標識符,被send或recv用來進行數據的接收和發送

    6.send()

    #include <sys/types.h>
    #include <sys/socket.h>
    int send(int sockfd, const void *msg, int len, int flags);
    參數說明:
    sockfd 是代表你與遠程程序連接的套接字描述符。
    msg 是一個指針,指向你想發送的信息的地址。
    len 是你想發送信息的長度。
    flags 發送標記。一般都設為0(你可以查看send 的man pages 來獲得其他的參數值并且明白各個參數所代表的含義,很多時候只要你手不懶,通過linux的man命令可以獲得很多詳細的說明,另外很多書籍或者博客信息也都是man的中文翻譯)。

    7.recv()

    #include <sys/types.h>
    #include <sys/socket.h>
    int recv(int sockfd, void *buf, int len, unsigned int flags);
    參數說明:
    sockfd 是你要讀取數據的套接字描述符。
    buf 是一個指針,指向你能存儲數據的內存緩存區域。
    len 是緩存區的最大尺寸。
    flags 是recv() 函數的一個標志,一般都為0

    到此你可以寫出一個簡單的c/s模式的通信來了。

    c/s模式是面向連接的demo

    server端:

    [cpp]?view plain?copy
  • <span?style="font-size:14px;">#include<stdio.h>??
  • #include<stdlib.h>??
  • #include<string.h>??
  • #include<errno.h>??
  • #include<sys/types.h>??
  • #include<sys/socket.h>??
  • #include<netinet/in.h>??
  • #define?MAXLINE?4096??
  • int?main(int?argc,?char**?argv)??
  • {??????
  • ????????int????listenfd,?connfd;??????
  • ????????struct?sockaddr_in?????servaddr;??????
  • ????????char????buff[4096];??????
  • ????????int?????n;??????
  • ????????if(?(listenfd?=?socket(AF_INET,?SOCK_STREAM,?0))?==?-1?)??
  • ????????{??????
  • ????????????????printf("create?socket?error:?%s(errno:?%d)\n",strerror(errno),errno);??????
  • ????????????????exit(0);??????
  • ????????}??????
  • ????????memset(&servaddr,?0,?sizeof(servaddr));??????
  • ????????servaddr.sin_family?=?AF_INET;??????
  • ????????servaddr.sin_addr.s_addr?=?htonl(INADDR_ANY);??????
  • ????????servaddr.sin_port?=?htons(6666);??????
  • ????????if(?bind(listenfd,?(struct?sockaddr*)&servaddr,?sizeof(servaddr))?==?-1)??
  • ????????{??????
  • ????????????????printf("bind?socket?error:?%s(errno:?%d)\n",strerror(errno),errno);??????
  • ????????????????exit(0);??????
  • ????????}??????
  • ????????if(?listen(listenfd,?10)?==?-1)??
  • ????????{??????
  • ????????????????printf("listen?socket?error:?%s(errno:?%d)\n",strerror(errno),errno);??????
  • ????????????????exit(0);??????
  • ????????}????????
  • ????????printf("======waiting?for?client's?request======\n");??????
  • ????????while(1)??
  • ????????{??????
  • ????????????????if(?(connfd?=?accept(listenfd,?(struct?sockaddr*)NULL,?NULL))?==?-1)??
  • ????????????????{??????????
  • ????????????????????????printf("accept?socket?error:?%s(errno:?%d)",strerror(errno),errno);??????????
  • ????????????????????????continue;??????
  • ????????????????}??????
  • ????????????????n?=?recv(connfd,?buff,?MAXLINE,?0);??????
  • ????????????????buff[n]?=?'\0';??????
  • ????????????????printf("recv?msg?from?client:?%s\n",?buff);??????
  • ????????????????close(connfd);??????
  • ????????}??????
  • ????????close(listenfd);??
  • }</span>??
  • client端:

    [cpp]?view plain?copy
  • <span?style="font-size:14px;">#include<stdio.h>??
  • #include<stdlib.h>??
  • #include<string.h>??
  • #include<errno.h>??
  • #include<sys/types.h>??
  • #include<sys/socket.h>??
  • #include<netinet/in.h>??
  • #define?MAXLINE?4096??
  • int?main(int?argc,?char**?argv)??
  • {??????
  • ????????int????sockfd,?n;??????
  • ????????char????recvline[4096],?sendline[4096];??????
  • ????????struct?sockaddr_in????servaddr;??????
  • ????????if(?argc?!=?2)??
  • ????????{??????
  • ????????????????printf("usage:?./client?<ipaddress>\n");??????
  • ????????????????exit(0);??????
  • ????????}??????
  • ????????if(?(sockfd?=?socket(AF_INET,?SOCK_STREAM,?0))?<?0)??
  • ????????{?????
  • ????????????????printf("create?socket?error:?%s(errno:?%d)\n",?strerror(errno),errno);??????
  • ????????????????exit(0);??????
  • ????????}??????
  • ????????memset(&servaddr,?0,?sizeof(servaddr));??????
  • ????????servaddr.sin_family?=?AF_INET;??????
  • ????????servaddr.sin_port?=?htons(6666);??????
  • ????????if(?inet_pton(AF_INET,?argv[1],?&servaddr.sin_addr)?<=?0)??
  • ????????{??????
  • ????????????????printf("inet_pton?error?for?%s\n",argv[1]);??????
  • ????????????????exit(0);??????
  • ????????}??????
  • ????????if(?connect(sockfd,?(struct?sockaddr*)&servaddr,?sizeof(servaddr))?<?0)??
  • ????????{??????
  • ????????????????printf("connect?error:?%s(errno:?%d)\n",strerror(errno),errno);??????
  • ????????????????exit(0);??????
  • ????????}??????
  • ????????printf("send?msg?to?server:?\n");?????
  • ????????
  • ?while(1)
  • {
  • ??fgets(sendline,?4096,?stdin);?????
  • ?if(?send(sockfd,?sendline,?strlen(sendline),?0)?<?0)?????
  • ?{??????????
  • ?????????printf("send?msg?error:?%s(errno:?%d)\n",?strerror(errno),?errno);?????
  • ????????????????exit(0);??????
  • ????????} ? ??

  • }
  • ????????close(sockfd);??????
  • ????????exit(0);??
  • }??
  • </span> ?

  • ??fgets(sendline,?4096,?stdin);??????
  • ????????if(?send(sockfd,?sendline,?strlen(sendline),?0)?<?0)??????
  • ????????{??????
  • ????????????????printf("send?msg?error:?%s(errno:?%d)\n",?strerror(errno),?errno);??????
  • ????????????????exit(0);??????
  • ????????} ? ??
  • 總結

    以上是生活随笔為你收集整理的socket通信之最简单的socket通信的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。