################服务端
1.准备工作导入头文件
1 #include<WinSock2.h> 2 #pragma comment(lib, "ws2_32.lib")
2.确定版本信息
MSAStartup :异步套接字的启动命令 . 第一个参数是版本请求,高阶字节是修订版本,低阶字节是主版本号
第二个参数是一个结构体,接收socket的实现细节
1 WSADATA wsaData; 2 WSAStartup(MAKEWORD(2,2),&wsaData); 3 if(LOBYTE(wsaData.wVersion)!=2 || HIBYTE(wsaData.wVersion)!=2) 4 { 5 printf("请求版本失败"); 6 return ; 7 }
3.创建socket
第一个参数表示要使用的协议族 : AF_INET IPv4的地址 和 端口号(16位)的组合
第二个参数表示类型 SOCK_STREAM 流式socket , 面向连接的socket
第三个参数指定协议 IPPROTO_TCP 使用 TCP 传输协议
1 SOCKET serverSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP) 2 if(INVALID_SOCKET == severSocket) 3 { 4 printf("套接字创建失败"); 5 return ; 6 }
4.初始化协议地址族
1 SOCKADDR_IN serverAddr = {0}; //初始化协议地址 2 serverAddr.sin_family = AF_INET;//必须和创建socket的IP协议一致 3 serverAddr.sin_prot = htons(8888); //服务器端口,客户端通过这个端口连接 4 5 //ip地址是点分格式的字符串 , 用inet_addr来转换整数 6 serverAddr.sin_addr.S_un.S_addr = inet_addr("172.0.0.1");
5.绑定
1 if(SOCKET_ERROR == bind(serverSocket , (SOCKADDR*)&serverAddr , sizeof(serverAddr))) 2 { 3 printf("绑定失败"); 4 closesocket(serverSocket); //释放socket 5 WSACleanup(); //关闭套接字 6 return ; 7 } 8 printf("绑定成功");
6.监听
listen的第二个参数是监听的个数 , 等待连接的队列最大长度
1 if(SOCKET_ERROR == listen(serverSocket, 10)) 2 { 3 printf("监听失败"); 4 closesocket(serverSocket); //释放socket 5 WSACleanup(); //关闭套接字 6 return ; 7 } 8 printf("监听成功");
7.接受连接
accetp 第二第三个参数可以给NULL 表示不保存连接进来的客户端(ip)信息 , 不给NULL 表示保存客户端信息
1 SOCKADDR_IN clientAddr = {0}; 2 int len = sizeof(clientAddr); 3 SOCKET clientSocket = accept(serverSocket,(SOCKADDR*)&clientAddr, &len); //阻塞函数 4 if(clientSocket == INVALID_SOCKET) 5 { 6 printf("连接失败"); 7 closesocket(serverSocket); //释放socket 8 WSACleanup(); //关闭套接字 9 return ; 10 } 11 printf("连接成功"); 12 printf("客户端(%s) " , inet_ntoa(clientAddr.sin_addr));
8.开始通讯
recv的第一个参数表示客户端的socket 进行接收数据 , 第四个参数表示收发方式默认为0, 一次收完
1 char recvBuff[128] = {}; 2 while(1) 3 { 4 memset(recvBuff, 0 , sizeof(recvBuff)); 5 if(recv(clientSocket , recvBuff, sizeof(recvBuff)-1 , 0) >0) //阻塞函数 6 { 7 printf(">>%s " , recvBuff); 8 } 9 10 char sendBuff[128] = {}; 11 memset(sendBuff, 0 , sizeof(sendBuff)); 12 printf("请输入: "); 13 scanf_s("%s" , sendBuff, sizeof(sendBuff)-1); 14 //一次收发 15 send(clientSocket , sendBuff, strlen(sendBuff), 0); 16 }
9.关闭socket
1 closesocket(clientSocket); 2 closesocket(serverSocket); 3 WSACleanup();
################客户端
1.准备工作导入头文件
2.确定版本信息
MSAStartup :异步套接字的启动命令 . 第一个参数是版本请求,高阶字节是修订版本,低阶字节是主版本号
第二个参数是一个结构体,接收socket的实现细节
3.创建socket
第一个参数表示要使用的协议族 : AF_INET IPv4的地址 和 端口号(16位)的组合
第二个参数表示类型 SOCK_STREAM 流式socket , 面向连接的socket
第三个参数指定协议 IPPROTO_TCP 使用 TCP 传输协议
1 SOCKET clientSocket= socket(AF_INET,SOCK_STREAM,IPPROTO_TCP) 2 if(INVALID_SOCKET == clientSocket) 3 { 4 printf("套接字创建失败"); 5 return ; 6 }
4.初始化协议地址族(初始化的是服务端的ip地址及端口, 表示连接用)
1 SOCKADDR_IN clientAddr = {0}; //初始化协议地址 2 clientAddr.sin_family = AF_INET;//必须和创建socket的IP协议一致 3 clientAddr.sin_prot = htons(8888); //服务器端口,客户端通过这个端口连接 4 5 //ip地址是点分格式的字符串 , 用inet_addr来转换整数 6 clientAddr.sin_addr.S_un.S_addr = inet_addr("172.0.0.1");
5.连接
1 if(SOCKET_ERROR == connect(clientSocket , (sockaddr *)&clientAddr , sizeof(clientAddr))) 2 { 3 printf("连接失败"); 4 closesocket(clientSocket); //释放socket 5 WSACleanup(); //关闭套接字 6 return ; 7 } 8 printf("连接成功");
8.开始通讯
recv的第一个参数表示客户端的socket 进行接收数据 , 第四个参数表示收发方式默认为0, 一次收完
1 char sendBuff[128] = {}; 2 while(1) 3 { 4 memset(sendBuff, 0 , sizeof(sendBuff)); 5 printf("请输入: "); 6 scanf_s("%s" , sendBuff, sizeof(sendBuff)-1); 7 //一次收发 8 send(clientSocket , sendBuff, strlen(sendBuff), 0); 9 10 char recvBuff[128] = {}; 11 memset(recvBuff, 0 , sizeof(recvBuff)); 12 if(recv(clientSocket , recvBuff, sizeof(recvBuff)-1 , 0) >0) //阻塞函数 13 { 14 printf(">>%s " , recvBuff); 15 } 16 }
9.关闭socket
1 closesocket(clientSocket); 2 WSACleanup();