1. 頭文件
2. API函數
3. 最簡單的服務器和對應的客戶端C語言實現
3.1 server
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(int argc, char** argv) { char hello[] = "hello world"; struct sockaddr_in sa; int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); if (-1 == SocketFD) { perror("cannot create socket"); //鎵撳嵃浠€涔堝師鍥犲嚭閿? exit(EXIT_FAILURE); // 1 } memset(&sa, 0, sizeof(sa)); //c鐨勪範鎯? 鏄劇ず鍒濆鍖? //瀹氫箟浜唅p鍦板潃鍜岀鍙e彿 sa.sin_family = AF_INET; sa.sin_port = htons(2222); //htons鎶婃搷浣滅郴緇熺殑瀛楄妭搴忥紝杞寲涓虹綉緇滅殑瀛楄妭搴?==> Linux涓婂皬絝?->澶х sa.sin_addr.s_addr = htonl(INADDR_ANY); //緇戝畾絝彛鍙? //澶辮觸: 宸茬粡緇戝畾錛屾垨鑰呭皬浜?024鐨勭鍙?闇€瑕佹潈闄? if (-1 == bind(SocketFD, (struct sockaddr*)&sa, sizeof(sa))) { perror("bind failed"); exit(EXIT_FAILURE); } //鐩戝惉, 10:鍚庨潰鍐嶈 if (-1 == listen(SocketFD, 10)) { perror("accept failed\n"); close(SocketFD); exit(EXIT_FAILURE); } //鏈嶅姟鍣ㄥ紑濮嬪伐浣? accept:鎺ユ敹涓€嬈′笁嬈℃彙鎵嬫垚鍔熺殑瀹㈡埛絝繛鎺? for (;;) { int ConnectFD = accept(SocketFD, NULL, NULL); if (0 > ConnectFD) { perror("accept failed"); exit(EXIT_FAILURE); } int writeSize = 0; size_t totalWrite = 0; while (totalWrite < sizeof(hello)) { writeSize = write(ConnectFD, hello + totalWrite, sizeof(hello) - totalWrite); if (-1 == writeSize) { perror("write failed"); close(ConnectFD); close(SocketFD); exit(EXIT_FAILURE); } totalWrite += writeSize; } if (-1 == shutdown(ConnectFD, SHUT_RDWR)) { perror("shutdown failed\n"); close(ConnectFD); close(SocketFD); exit(EXIT_FAILURE); } close(ConnectFD); } close(SocketFD); return EXIT_SUCCESS; }
3.2 client
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main(int argc, char *argv[]) { struct sockaddr_in sa; int res; //tcp int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); //資源不夠 if (-1 == SocketFD) { perror("cannot create socket"); exit(EXIT_FAILURE); } //初始化sa memset(&sa, 0, sizeof(sa)); //設置連接服務器的 ip和端口號 sa.sin_family = AF_INET; //端口號2222, htons把操作系統的字節序,轉化為網絡的字節序 sa.sin_port = htons(2222); //連接本地ip地址 res = inet_pton(AF_INET, "127.0.0.1", &sa.sin_addr); //客戶端,設置連接服務器 //失敗,則釋放資源 if (-1 == connect(SocketFD, (struct sockaddr*)&sa, sizeof(sa))) { perror("connect failed\n"); close(SocketFD); exit(EXIT_FAILURE); } char buffer[512]; int totalRead = 0; for (;;) { int readSize = 0; readSize = read(SocketFD, buffer + totalRead, sizeof(buffer) - totalRead); if (readSize == 0) { //read all break; } else if (readSize == -1) { perror("read failed"); close(SocketFD); exit(EXIT_FAILURE); } char buffer[512]; int totalRead = 0; for (;;) { int readSize = 0; readSize = read(SocketFD, buffer + totalRead, sizeof(buffer) - totalRead); if (readSize == 0) { //read all break; } else if (readSize == -1) { perror("read failed"); close(SocketFD); exit(EXIT_FAILURE); } totalRead += readSize; } buffer[totalRead] = 0; printf("get from server: %s\n", buffer); /* perform read wirte operations ...*/ (void)shutdown(SocketFD, SHUT_RDWR); close(SocketFD); return EXIT_SUCCESS; }
當服務器主動關閉連接的時候,會出現 TIME_WAIT狀態(哪一邊主動關閉連接,TIME_WAIT發生在哪一邊)