Winsock API TCP/IP网络通信
标签:描述 accept 控制 port sock 顺序 版本 系统 style
通信流程如下:
1、Winsock库的装入、初始化
#pragma comment(lib,"WS2_32.lib")、WSAStartup()
2、套接字的创建(服务器端是监听套接字)
socket()
3、绑定套接字到指定的IP地址和端口
bind()
4、设置套接字进入监听状态(服务器端)+接受连接请求(服务器端)
listen()、accept()
5、请求与服务器连接
connect()
6、收发数据
send()、recv()
7、关闭套接字,释放Winsock库
closesocket()、WSACleanup()
详细流程如下:
服务器端代码:
// TCPServer.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include #pragma comment(lib,"WS2_32.lib") //包含相应库文件
int main()
{
WSADATA wsaData;//结构体。(DLL库)建议版本/支持的最高版本/描述字符串/系统状态字符串/同时支持最大套接字数量
WORD sockVersion = MAKEWORD(2, 0);//windows socket api 版本
::WSAStartup(sockVersion, &wsaData); //必须首先执行。其指定了API版本,取得DLL库的详细信息
//int a=::WSAGetLastError();//WSAStartup函数执行成功返回0,否则使用WSAGetLastError查看出错信息
SOCKET s = ::socket(AF_INET, //套接字使用的地址格式,winSock中只能是AF_INET
SOCK_STREAM, //指定套接字类型(SOCK_DGRAM/RAW(数据报/原始))
IPPROTO_TCP);//使用协议类型,前一个是SOCK_STREAM/SOCK_DGRAM时可以为0。
if (s == INVALID_SOCKET)
{
printf("Failed socket()\n");
::WSACleanup();//对应WSAStartup
return 0;
}
sockaddr_in sin;
sin.sin_family = AF_INET; //地址家族(只能是AF_INET)
sin.sin_port = htons(8888); //端口地址(网络字节顺序)为0时自动分配(1024~5000)
sin.sin_addr.S_un.S_addr = INADDR_ANY;//IP地址。为INADDR_ANY自动取得本机所有IP
if (::bind(s, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)//(套接字句柄,本地地址,地址长度)
{
printf("Failed bind()\n");
::WSACleanup();
return 0;
}
if (::listen(s, 2) == SOCKET_ERROR)//(套接字句柄,监听队列中允许保持的尚未处理的最大连接数)
{
printf("Failed listen()\n");
::WSACleanup();
return 0;
}
sockaddr_in remoteAddr;
int nAddrLen = sizeof(remoteAddr);
SOCKET client;
char szText[] = "TCPServer!\r\n";
while (TRUE)
{
client = ::accept(s, //套接字句柄
(SOCKADDR*)&remoteAddr,//取得对方地址信息
&nAddrLen);//指定remoteAddr空间大小,并且返回地址实际长度
//accept接受到来的连接,为这个连接创建新的套接字,此套接字是处理实际连接的套接字
if (client == INVALID_SOCKET)
{
printf("Failed accept()\n");
continue;
}
printf("接收到一个链接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));//inet_ntoa
::send(client, szText, strlen(szText), 0);//发送数据(套接字,数据,数据长度,调用方式(通常为0))
::closesocket(client);//关闭
}
::closesocket(s);//关闭
::WSACleanup();//clean
return 0;
}
客户机代码:
// TCPClient.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include
#include#pragma comment(lib,"WS2_32.lib")
int main()
{
WSADATA wsaData;
WORD sockVerion = MAKEWORD(2, 0);
::WSAStartup(sockVerion, &wsaData);
SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (s == INVALID_SOCKET)
{
printf("Failed socket()\n");
::WSACleanup();
return 0;
}
sockaddr_in servAddr; //远程地址信息
servAddr.sin_family = AF_INET;
servAddr.sin_port = htons(8888);
servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//没有联网可以直接写127.0.0.1
if (::connect(s, //套接字
(sockaddr*)&servAddr, //远程地址信息
sizeof(servAddr)) == -1)//地址长度
{
printf("Failed connect()\n");
::WSACleanup();
return 0;
}
char buff[256];
int nRecv = ::recv(s, buff, 256, 0);//接收(套接字,缓冲区,长度,调用方式(通常为0))
if (nRecv > 0)
{
buff[nRecv] = ‘\0‘;
printf("接收到数据:%s", buff);
}
::closesocket(s);
::WSACleanup();
return 0;
}
Winsock API TCP/IP网络通信
标签:描述 accept 控制 port sock 顺序 版本 系统 style
原文地址:https://www.cnblogs.com/cteng-common/p/WinsockCommunicate.html
评论