socket編程——TCP_TCP

來源:互聯網
上載者:User
函數流程框圖:


建立: int  socket(int  domain,int  type,int  protocol);

domain——>協議域:

AF_INET————IPV4。

AF_INET6————IPV6。

AF_LOCAL————Unix域。

type——>類型:

SOCK_STREAM——流式通訊端,TCP協議支援該通訊端(提供連線導向,可靠的Data Transmission Service,資料按位元組流,按順序收發,保證在傳輸過程中無丟失,無冗餘)。

SPCK_DGRAM———資料通訊端,UDP協議支援該通訊端(提供面向不需連線的服務,資料收發無序,不能保證資料的準確到達)。

SOCK_RAM————原始通訊端,常用於檢測新協議。允許對低於傳輸層的協議或物理網路直接存取。

protocol——>協議:

0————自動根據type匹配協議。

IPPROTO_TCP。

IPPROTO_UDP。

傳回值:

>0時為socket描述符;-1為失敗。 關閉: int  close(int  fd); int  shutdown(int sockfd,int howto);

sockfd——socket通訊端。

howto:

SHUT_RD———值為0;關閉串連的讀。

SHUT_WR———值為1;關閉串連的寫。

SHUT_RDWR——值為2;串連的讀和寫都關閉。 綁定: int  bind(int  socket,const struct sockaddr* address,socklen_t address_len);

socket—————通訊端描述符。

address—————地址和連接埠號碼。

address_len———address緩衝區的長度。

傳回值——————0為成功;SOCKET_ERROR為失敗。 監聽: int listen(int sockfd,int backlog);

socket—————監聽的socket描述符。

backlog————排隊的最大串連個數。

傳回值—————0為成功;-1為失敗。 串連: int connect(int sockfd,const struct sockaddr* addr,socklen_t,addrlen);

sockfd————用戶端的socket描述符。

addr—————伺服器的socket地址。

addrlen————伺服器的socket地址的長度。

傳回值—————0為成功l-1為失敗。 接受: int accept(int sockfd,struct socketaddr* addr,socklen_t* addrlen);

sockfd————伺服器的socket描述符,或,監聽socket描述符。

addr—————用戶端的socket地址。

addrlen————用戶端的socket地址長度。

傳回值————非-1為串連描述符;-1為失敗。 發送: ssize_t write(int fd,const void* buf,size_t len);

fd————檔案描述符。

buf————寫入的資料。

len————寫入資料長度。

傳回值———>0為實際所寫的位元組數;<0出錯。 ssize_t  send(int sockfd,const void* buf,size_t len,int flags);

flags——通常為0。

傳回值及其他——同上。 ssize_t sendto(int sockdf,const void* buf,size_t len,int flags,const struct sockaddr* dest_addr,socklen_t addrlen);

dest_addr———目標socket地址。

addrlen————目標socket地址長度。

傳回值及其他——同上。 接收: ssize_t read(int fd,void* buf,size_t len);

buf————讀取檔案。

傳回值——0為讀到檔案的結束;>0實際所讀到的位元組數;<0出錯。 ssize_t recv(int sockfd,void* buf,size_t len,int flags);

flags——————通常為0。

傳回值及其他——同上。 ssize_t recvfrom(int sockdf,void* buf,size_t len,int flags,const struct sockaddr* src_addr,socklen_t addrlen); src_addr————目標socket地址。 addrlen—————目標socket地址長度。 傳回值及其他——同上。 結構體: struct sockaddr:

struct sockaddr {    unsigned short sa_family;    char sa_data[14];};
struct sockaddr_in:
struct sockaddr_in{    short sin_family;    unsigned short sin_port;    struct in_addr sin_addr;    unsigned char sin_zero[8];};
struct in_addr:
struct in_addr {    in_addr_t s_addr;};
in_addr_t:
typedef unsigned int in_addr_t;
struct sockaddr_in6(IPV6):
struct sockaddr_in6{   //IPv6 為固定的24 位元組長度   uint8_t sin6_len;    //地址簇類型,為AF_INET6   sa_family_t sin6_family;   //16 位連接埠號碼,網路位元組序   in_port_t sin6_port;   //32 位流標籤   uint32_t sin6_flowinfo;   //128 位IP 位址   struct in6_addr sin6_addr;}
特殊地址設定: 通配地址(0.0.0.0): 主機上所有IP,多網卡並用。 ipv4:
in_addr.sin_addr.s_addr = htonl(INADDR_ANY);
ipv6:
in6_addr.sin6_addr = in6addr_any;
迴環地址(127.0.0.1): 本地虛擬介面,無網卡可用,也不需要網卡。用於檢查本網協議。 ipv4:
in_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
ipv6:
in6_addr.sin6_addr = in6addr_loopback;
廣播位址: 受限廣播位址——255.255.255.255 子網廣播位址——xxx.xxx.xxx.255 全子網廣播———xxx.xxx.255.255 ipv4:
in_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
ipv6: 無。
代碼: tcp_cliect:
#include <stdio.h>#include <string.h>#include <arpa/inet.h>#include <sys/socket.h>void show_info(int connfd){struct sockaddr_in local_addr;bzero(&local_addr,sizeof(local_addr));socklen_t local_addr_len = sizeof(local_addr);getsockname(connfd,(struct sockaddr*)&local_addr,&local_addr_len);printf("client local %s:%d\n",inet_ntoa(local_addr.sin_addr),ntohs(local_addr.sin_port));struct sockaddr_in peer_addr;bzero(&peer_addr,sizeof(peer_addr));socklen_t peer_addr_len = sizeof(peer_addr);getpeername(connfd,(struct sockaddr*)&peer_addr,&peer_addr_len);printf("clinet peer %s:%d\n",inet_ntoa(peer_addr.sin_addr),ntohs(peer_addr.sin_port));}int main(int argc,char* argv[]){if(4 != argc){printf("usage:%s <ip> <#port> <message>\n",argv[0]);return 1;}int connfd = socket(AF_INET,SOCK_STREAM,0);if(-1 == connfd){perror("socket err");return 1;}struct sockaddr_in remote_addr;bzero(&remote_addr,sizeof(remote_addr));remote_addr.sin_family = AF_INET;remote_addr.sin_addr.s_addr = inet_addr(argv[1]);remote_addr.sin_port = htons(atoi(argv[2]));if(-1 == connect(connfd,(struct sockaddr*)&remote_addr,sizeof(remote_addr))){perror("connect err");return 1;}show_info(connfd);write(connfd,argv[3],strlen(argv[3])+1);printf("client send:%s\n",argv[3]);char buf[BUFSIZ];bzero(buf,BUFSIZ);if(-1 == read(connfd,buf,BUFSIZ)){perror("read err");return 1;}printf("client recv:%s\n",buf);close(connfd);}
tcp_server:
#include <stdio.h>#include <string.h>#include <arpa/inet.h>#include <sys/socket.h>void show_info(int connfd){struct sockaddr_in local_addr;bzero(&local_addr,sizeof(local_addr));socklen_t local_addr_len = sizeof(local_addr);getsockname(connfd,(struct sockaddr*)&local_addr,&local_addr_len);printf("server local %s:%d\n",inet_ntoa(local_addr.sin_addr),ntohs(local_addr.sin_port));struct sockaddr_in peer_addr;bzero(&peer_addr,sizeof(peer_addr));socklen_t peer_addr_len = sizeof(peer_addr);getpeername(connfd,(struct sockaddr*)&peer_addr,&peer_addr_len);printf("server peer %s:%d\n",inet_ntoa(peer_addr.sin_addr),ntohs(peer_addr.sin_port));}int main(int argc,char* argv[]){if(3 != argc){printf("usage:%s <ip> <#port>\n",argv[0]);return 1;}int listenfd = socket(AF_INET,SOCK_STREAM,0);if(-1 == listenfd){perror("listenfd open err");return 1;}printf("socket create OK\n");int flag = 1;setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag));struct sockaddr_in local_addr;bzero(&local_addr,sizeof(local_addr));local_addr.sin_family = AF_INET;local_addr.sin_addr.s_addr = inet_addr(argv[1]); local_addr.sin_port = htons(atoi(argv[2]));if(-1 == bind(listenfd,(struct sockaddr*)&local_addr,sizeof(local_addr))){perror("bind err");return 1;}printf("bind OK\n");if(-1 == listen(listenfd,10)){perror("listen err");return 1;}printf("listen OK\n");struct sockaddr_in remote_addr;bzero(&remote_addr,sizeof(remote_addr));socklen_t remote_addr_len = sizeof(remote_addr);int connfd = accept(listenfd,(struct sockaddr*)&remote_addr,&remote_addr_len);if(-1 == connfd){perror("accept err");return 1;}show_info(connfd);printf("accept %s:%d\n",inet_ntoa(remote_addr.sin_addr),ntohs(remote_addr.sin_port));char buf[BUFSIZ];bzero(buf,BUFSIZ);if(-1 == read(connfd,buf,BUFSIZ-1)){perror("read err");return 1;}printf("server recv:%s\n",buf);if(-1 == write(connfd,buf,strlen(buf)+1)){perror("write err");return 1;}printf("server send:%s\n",buf);close(connfd);close(listenfd);}
結果:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.