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 "); 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 "); 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 "); 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 ", buffer); /* perform read wirte operations ...*/ (void)shutdown(SocketFD, SHUT_RDWR); close(SocketFD); return EXIT_SUCCESS; }
当服务器主动关闭连接的时候,会出现 TIME_WAIT状态(哪一边主动关闭连接,TIME_WAIT发生在哪一边)