近日忽然發現本身忘記了網絡編程,從新拾起一下。
幾個概念性東西:編程
不少時候介紹socket鏈接通信的時候,每每是上面這張圖。
右邊是服務器,左邊是客戶端。
服務器:
第一步: socket(), 是建立一個socket。這個過程咱們使用的語言和操做系統?其實就是和咱們調用http請求登陸是同樣的,會返回一個標識符,操做系統是服務端,咱們的程序是客戶端。
操做系統內部就作某些東西,多是建立一個socket,而後返回一個標識碼,經過這個標識碼,後面調用其餘的api,經過傳輸這個標識符,就能夠操做改socket。
第二步:bind(),去綁定ip和port,由於只有經過ip和port才能找到服務器。
第三步: listen(),去監聽,這個時候纔開始了action。判斷是不是這個地址,和端口,就能夠建立鏈接。
第四步:accept(),好比有一個鏈接來了,操做系統首先幫助咱們緩存起來,由於它不知道把這個鏈接的信息調用給誰,經過accept創建與操做系統的持久性鏈接,而後操做系統才能源源不斷的把鏈接信息給到咱們。
第五步或者第六步:若是沒有accept咱們的程序是沒法收到消息的,可是咱們的操做系統確定是收到了的,畢竟創建了鏈接。而咱們發現接受信息的時候,咱們調用的是
recv(hSocket,message,sizeof(message)-1,0),咱們和操做系統溝通接收信息,其實是操做系統是經過咱們提供的socket。windows
客戶端:
客戶端就比較簡單。
第一步: 一樣是建立一個socket,而後返回給咱們一個int 對象,也就是標識符。
第二步:而後只要給定地址,端口就能夠鏈接,就是connect。
第三步或者說第四步:和客戶端一致,在處理信息上沒有客戶端和服務端這個概念,只是維護同一套socket機制。api
本身理解的宏觀過程,自我理解存在偏差:
如下來自windows,c語言:
服務端:緩存
#include <stdio.h> #include <stdlib.h> #include <WinSock2.h> #pragma comment(lib, "ws2_32.lib") void ErrorHandling(char *message); int main(int argc, char * argv[]) { WSADATA wsaData; SOCKET hServerSock, hClientSock; SOCKADDR_IN serverAddr, clientAddr; int szclientAddr; char message[] = "Hello World"; if (argc != 2) { printf("Usage :%<port>\n",argv[0]); exit(1); } if (WSAStartup(MAKEWORD(2,2),&wsaData)!=0) { ErrorHandling("WASAtartup() error!"); } hServerSock = socket(PF_INET,SOCK_STREAM,0); if (hServerSock==INVALID_SOCKET) { ErrorHandling("socket() error"); } memset(&serverAddr,0,sizeof(serverAddr)); serverAddr.sin_family = AF_INET; serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); serverAddr.sin_port = htons(atoi(argv[1])); if (bind(hServerSock,(SOCKADDR *) &serverAddr,sizeof(serverAddr))==SOCKET_ERROR) { ErrorHandling("bind() error"); } if (listen(hServerSock,5)==SOCKET_ERROR) { ErrorHandling("listen() Error"); } szclientAddr = sizeof(clientAddr); hClientSock = accept(hServerSock,(SOCKADDR *) &serverAddr,&szclientAddr); if (hClientSock ==INVALID_SOCKET) { ErrorHandling("accept error"); } send(hClientSock,message,sizeof(message),0); closesocket(hClientSock); closesocket(hServerSock); WSACleanup(); return 0; } void ErrorHandling(char *message) { fputs(message,stderr); fputs('\n',stderr); exit(1); }
客戶端:服務器
#include <stdio.h> #include <stdlib.h> #include <winsock2.h> void ErrorHandling(char* message); int main(int argc,char* argv[]) { WSADATA wsaData; SOCKET hSocket; SOCKADDR_IN servAddr; char message[30]; int strLen; if (argc!=3) { printf("Usage : %s <IP> <port>\n",argv[0]); exit(1); } if (WSAStartup(MAKEWORD(2,2),&wsaData)!=0) { ErrorHandling("WSAStartup() error!"); } hSocket = socket(PF_INET,SOCK_STREAM,0); if (hSocket==INVALID_SOCKET) { ErrorHandling("socket() error"); } memset(&servAddr,0,sizeof(servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = inet_addr(argv[1]); servAddr.sin_port = htons(atoi(argv[2])); if (connect(hSocket,(SOCKADDR*) &servAddr,sizeof(servAddr))==SOCKET_ERROR) { ErrorHandling("connect() error!"); } strLen = recv(hSocket,message,sizeof(message)-1,0); if (strLen==-1) { ErrorHandling("read() error!"); } printf("Message from server:%s \n",message); closesocket(hSocket); WSACleanup(); return 0; } void ErrorHandling(char* message) { fputs(message,stderr); fputc('\n',stderr); exit(1); }