來源:微信公衆號「編程學習基地」
node
大端模式:指數據的高字節保存在內存的低地址
編程
例如:12345( 0x3039 ) 的存儲順序是 0x30、0x39
windows
小端模式:指數據的高字節保存在內存的高地址
服務器
例如:12345( 0x3039 ) 的存儲順序是 0x3九、0x30
微信
方法一:網絡
#include<stdio.h> int main(int argc, char *argv[]) { int i = 0x12345678; char c = i; if (c == 0x78) { printf("小端\n"); } else { printf("大端\n"); } return 0; }
方法二:socket
#include<stdio.h> int main(void) { int a = 0x12345678; char *p = (char *)&a; if (0x78 == *p) { printf("小端\n"); } else { printf("大端\n"); } return 0; }
方法三:tcp
#include<stdio.h> typedef union NODE { int i; char c; }Node; int main(int argc, char *argv[]) { Node node; node.i = 0x12345678; if (0x78 == node.c) { printf("小端\n"); } else { printf("大端\n"); } return 0; }
int WSAStartup ( WORD wVersionRequested, LPWSADATA pWSAData );
每個WSAStartup
都不準對應一個WSACleanup
的調用函數
int socket(int af, int type, int protocol);
AF_INET
、AF_INET6
、AF_LOCAL
WinSock只支持AF_INET
學習
SOCK_STREAM
、SOCK_DGRAM
、SOCK_RAW
等等
若是type爲SOCK_STREAM
,使用的是tcp協議
若是type爲SOCK_DGRAM
,使用的是udp協議
此時protocol
能夠指定爲0
若是type爲SOCK_RAW
,使用的是原始套接字,protocol能夠去自定義協議,例如ICMP等協議
struct sockaddr_in { short int sin_family, //地址家族 unsigned short int sin_port, //端口號 struct in_addr sin_addr, //IP地址 unsigned char sin_zero[8], //空字節,設爲0 }
struct in_addr:
struct in_addr{ unsigned long s_addr; }
inet_addr()
將一個點分十進制字符串轉化爲二進制的數
in_addr_t inet_addr(const char* cp);
inet_ntoa()
將二進制數轉換爲一個點分十進制字符串
char *inet_ntoa(struct in_addr);
TCP/IP協議統一使用網絡字節順序,即大端
u_short htons(u_short hostshurt) //主機字節順序轉網絡字節順序 u_long htonl(u_long hostshurt) //主機字節順序轉網絡字節順序 u_short ntohs(u_short hostshurt) //網絡字節順序轉主機字節順序 u_long ntohl(u_long hostshurt) //網絡字節順序轉主機字節順序
一般使用htons
來進行端口轉換
int bind( SOCKET s, //套接字句柄 onst struct sockaddr* name, //本地地址 int namelen //地址長度 );
int listen( SOCKET s, //套接字句柄 int backlog //監聽隊列容許保持的最大鏈接數量 );
SOCKET accept( SOCKET s, //套接字句柄 struct sockaddr* addr, //協議族瀆職 int* addrlen //地址長度 );
int connect( SOCKET s, //套接字句柄 const struct sockaddr* name, //協議族地址 int namelen //地址長度 );
#include <winsock2.h> // 爲了使用Winsock API函數 #include <stdio.h> #include <stdlib.h> #include <windows.h> // 告訴鏈接器與WS2_32庫鏈接 #pragma comment(lib,"WS2_32.lib") int main(int argc, char* argv[]) { // 初始化WS2_32.dll WSADATA wsaData; WORD sockVersion = MAKEWORD(2, 2); WSAStartup(sockVersion, &wsaData); //請求了一個2.2版本的socket // 建立套節字 SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == INVALID_SOCKET) { printf("Failed socket() \n"); WSACleanup(); return 0; } // 填充sockaddr_in結構 sockaddr_in sin; sin.sin_family = AF_INET; sin.sin_port = htons(8888); //8888端口 //sin.sin_addr.S_un.S_addr = INADDR_ANY; //本地地址 sin.sin_addr.S_un.S_addr = inet_addr("169.254.211.52"); //172.19.12.44 // 綁定這個套節字到一個本地地址 if (bind(s, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR) { printf("Failed bind() \n"); WSACleanup(); return 0; } // 進入監聽模式 if (listen(s, 2) == SOCKET_ERROR) //最大鏈接數爲2 { printf("Failed listen()"); WSACleanup(); return 0; } printf("Start listen:\n"); // 循環接受客戶的鏈接請求 sockaddr_in remoteAddr; int nAddrLen = sizeof(remoteAddr); SOCKET client; char szText[] = "hello!\n"; while (TRUE) { // 接受一個新鏈接 client = accept(s, (SOCKADDR*)&remoteAddr, &nAddrLen); if (client == INVALID_SOCKET) { printf("Failed accept()"); continue; } printf(" 接受到一個鏈接:%s \r\n", inet_ntoa(remoteAddr.sin_addr)); // 向客戶端發送數據 send(client, szText, strlen(szText), 0); // 關閉同客戶端的鏈接 closesocket(client); } // 關閉監聽套節字 closesocket(s); // 釋放WS2_32庫 WSACleanup(); return 0; }
#include <winsock2.h> #include <stdio.h> #include <windows.h> // 告訴鏈接器與WS2_32庫鏈接 #pragma comment(lib,"WS2_32.lib") int main(int argc, char* argv[]) { // 初始化WS2_32.dll WSADATA wsaData; WORD sockVersion = MAKEWORD(2, 2); WSAStartup(sockVersion, &wsaData); // 建立套節字 SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == INVALID_SOCKET) { printf("Failed socket() \n"); WSACleanup(); return 0; } // 填寫遠程地址信息 sockaddr_in servAddr; servAddr.sin_family = AF_INET; servAddr.sin_port = htons(8888); // 若是你的計算機沒有聯網,直接使用本地地址127.0.0.1 servAddr.sin_addr.S_un.S_addr = inet_addr("169.254.211.52"); if (connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1) { printf("Failed connect() \n"); WSACleanup(); return 0; } // 接收數據 char buff[256]; int nRecv = recv(s, buff, 256, 0); if (nRecv > 0) { buff[nRecv] = '\0'; printf(" 接收到數據:%s", buff); } // 關閉套節字 closesocket(s); // 釋放WS2_32庫 WSACleanup(); return 0; }