近日忽然发现本身忘记了网络编程,从新拾起一下。
几个概念性东西:编程
不少时候介绍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); }