編輯:關於Android編程
int socket(int af, int type, int protocol)返回 Socket 描述符 af: 地址類型
// 示例 int tcp_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int udp_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); int tcp_socket = socket(AF_INET, SOCK_STREAM, 0); int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
int bind(int sock, struct sockaddr *addr, socklen_t addrlen);返回值: 0 正常 / -1 錯誤 sock: Socket 文件描述符 addr: sockaddr 結構體變量指針(一般用 sockaddr_in / sockaddr_in6 強轉) addrlent: arrd 結構體大小(一般用 sizeof() 計算得出)
// 示例
//將創建的套接字與IP地址 127.0.0.1、端口 1234 綁定:
//創建套接字
int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//創建sockaddr_in結構體變量
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr)); //每個字節都用0填充
serv_addr.sin_family = AF_INET; //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具體的IP地址
serv_addr.sin_port = htons(1234); //端口
//將套接字和IP、端口綁定 使用 sockaddr_in 強轉成 sockaddr
bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));
int connect(int sock, struct sockaddr *serv_addr, socklen_t addrlen);返回值: 正常返回 0 sock: Socket serv_addr: addrlen:
int listen(int sock, int backlog);返回值: 正常返回 0 / 否則 -1 sock: backlog: 最大請求隊列長度
int accept(int sock, struct sockaddr *addr, socklen_t *addrlen);返回值: 新的套接字,表示客戶端的套接字 sock: 服務器端的 Socket addr: 新建的用來接收地址信息的結構體指針 addrlen: 接收地址信息的結構體大小
accpet 會阻塞當前線程直到有新的請求到來。
ssize_t write(int fd, const void *buf, size_t nbytes);返回值: 成功則返回字節數,否則返回 -1 fd: Socket buf: 寫入數據的緩沖區地址指針 nbytes: 寫入數據的字節數
數據只是寫入到緩沖區,但是什麼時候發送不由程序員控制。
ssize_t read(int fd, void *buf, size_t nbytes);返回值: 成功則返回字節數,文件尾則返回 0,失敗返回 -1 fd: Socket buf: 用來接收數據的緩沖區地址指針 nbytes: 要讀取數據的字節數
只是讀取緩沖區數據
int shutdown(int sock, int howto);返回值: 成功 0 / 失敗 -1 sock: Socket howto: 斷開方式
int close(int fd);返回值: 成功 0 / 失敗 -1 fd: Socket
簡單的在服務器端建立 Socket 並開始監聽,然後在客戶端進行連接並接收數據。
服務器端#include客戶端#include #include #include #include #include #include int main(){ //創建套接字 int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //將套接字和IP、端口綁定 struct sockaddr_in serv_addr; memset(&serv_addr, 0, sizeof(serv_addr)); //每個字節都用0填充 serv_addr.sin_family = AF_INET; //使用IPv4地址 serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具體的IP地址 serv_addr.sin_port = htons(1234); //端口 bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); //進入監聽狀態,等待用戶發起請求 listen(serv_sock, 20); //接收客戶端請求 struct sockaddr_in clnt_addr; socklen_t clnt_addr_size = sizeof(clnt_addr); int clnt_sock = accept(serv_sock, (struct sockaddr*)&clnt_addr, &clnt_addr_size); //向客戶端發送數據 char str[] = "Hello World!"; write(clnt_sock, str, sizeof(str)); //關閉套接字 close(clnt_sock); close(serv_sock); return 0; }
#include#include #include #include #include #include #include int main(){ //創建套接字 int sock = socket(AF_INET, SOCK_STREAM, 0); //向服務器(特定的IP和端口)發起請求 struct sockaddr_in serv_addr; memset(&serv_addr, 0, sizeof(serv_addr)); //每個字節都用0填充 serv_addr.sin_family = AF_INET; //使用IPv4地址 serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); //具體的IP地址 serv_addr.sin_port = htons(1234); //端口 connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); //讀取服務器傳回的數據 char buffer[40]; read(sock, buffer, sizeof(buffer)-1); printf("Message form server: %s\n", buffer); //關閉套接字 close(sock); return 0; }
創建一個 UDP 連接的 Socket,服務器不斷的接收客戶端的消息,然後返回回去。
服務器#include#include #include #include #include #include #include #include #define BUF_SIZE 100 int main(){ // 創建套接字 int serv_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); // 綁定套接字 sockaddr_in serv_addr; memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = PF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); // 自動獲取 ip 地址 serv_addr.sin_port = htons(1234); bind(serv_sock, (sockaddr *)&serv_addr, sizeof(sockaddr)); // 接收客戶端請求 sockaddr clin_addr; socklen_t clin_size = sizeof(sockaddr); char buffer[BUF_SIZE]; while (1) { int str_len = recvfrom(serv_sock, buffer, BUF_SIZE, 0, &clin_addr, &clin_size); printf("Message form clinet: %s\n", buffer); sendto(serv_sock, buffer, str_len, 0, &clin_addr, clin_size); } close(serv_sock); return 0; }
#include#include #include #include #include #include #include #define BUF_SIZE 100 int main() { // 創建套接字 int clin_sock = socket(PF_INET, SOCK_DGRAM, 0); // 服務器地址 sockaddr_in serv_addr; memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = PF_INET; serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); serv_addr.sin_port = htons(1234); //不斷獲取用戶輸入並發送給服務器,然後接受服務器數據 sockaddr fromAddr; socklen_t addrLen = sizeof(fromAddr); while(1){ char buffer[BUF_SIZE] = {0}; printf("Input a string: "); gets(buffer); sendto(clin_sock, buffer, strlen(buffer), 0, (struct sockaddr*)&serv_addr, sizeof(serv_addr)); int strLen = recvfrom(clin_sock, buffer, BUF_SIZE, 0, &fromAddr, &addrLen); buffer[strLen] = 0; printf("Message form server: %s\n", buffer); } close(clin_sock); return 0; }
// 示例
unsigned optVal;
int optLen = sizeof(int);
getsockopt(servSock, SOL_SOCKET, SO_SNDBUF, (char*)&optVal, &optLen);
printf("Buffer length: %d\n", optVal);
struct sockaddr {
__uint8_t sa_len;
sa_family_t sa_family;
char sa_data[14];
};
sa_len: 結構體總長度 sa_family: 地址族
struct sockaddr_in {
__uint8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
sin_len: 結構體長度 sin_family: 地址族(一般是 AF_INET) sin_port: 16位端口號,需要用 htons() 進行轉換 sin_addr: in_addr 類型的結構體,包含一個 32 位的 ip 地址,定義在
struct sockaddr_in6 {
__uint8_t sin6_len;
sa_family_t sin6_family;
in_port_t sin6_port;
__uint32_t sin6_flowinfo;
struct in6_addr sin6_addr;
__uint32_t sin6_scope_id;
};
sin6_len: 結構體長度 sin6_family: 地址族(一般是 AF_INET6) sin6_port: 16 位端口號,需要用 htons() 進行轉換 sin6_flowinfo: Ipv6 流信息 sin6_addr: Ipv6 地址 sin6_scope_id: 接口范圍 id
struct in_addr {
in_addr_t s_addr;
};
struct in6_addr {
union {
__uint8_t __u6_addr8[16];
__uint16_t __u6_addr16[8];
__uint32_t __u6_addr32[4];
} __u6_addr; /* 128-bit IP6 address */
};
``
## hostent - 通過域名獲取的 ip 地址結構
* h_name:官方域名 * h_aliases:別名, 可以通過多個域名訪問同一主機 * h_addrtype:地址族, IPv4 對應 AF_INET, IPv6 對應 AF_INET6 * h_length:保存IP地址長度. IPv4 的長度為4個字節,IPv6 的長度為16個字節 * h_addr_list:以整數形式保存域名對應的IP地址, 可能會分配多個IP地址
從Android代碼中來記憶23種設計模式
本文轉載於 huachao1001的專欄相信大家都曾經下定決心把23種設計模式牢記於心,每次看完之後過一段時間又忘記了~,又得回去看,腦子裡唯一依稀記得的是少
Android 的媒體路由功能應用與框架解析
一、功能描述 Android 的媒體路由API被設計用來允許多種媒體(視頻、音樂、圖片)在與ANDROID設備連接(無線或有線)的輔助設備(如電視、立
Android Material Design動畫
最近在看一些關於Material Design的東西,還記得在博客《你所不知道的Activity轉場動畫——ActivityOptions》中,我
Android Contact provider基礎
Contact providerContact provider是一個強大而又靈活的 Android 組件,用於管理設備上有關聯系人數據的中央存儲庫。 Contact p