Windows网络编程 TCP/IP模型
主机流程:
1,建立流式套接字
2,与本地地址绑定
3,通知TCP服务器准备好连接
4,等待客户端的连接
5,建立连接
6,在套接字上读/写数据
7,关闭套接字
8,关闭最初的套接字,关闭服务
代码:
// 服务器端.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#define sizeN 225
#include "winsock2.h" //WinSock2的头文件winsock2.h
#pragma comment(lib, "ws2_32.lib") //导入库文件ws2_32.lib,链接WinSock导入库
#include<iostream>
using namespace std;
int main()
{
WSADATA wsaData; //指向WASDATA结构体变量的指针
WORD wVersion = MAKEWORD(2, 2); //版本号
if (WSAStartup(wVersion, &wsaData) != 0) //加载WinSock动态链接库
{
cout << "加载winsock.dll失败!\n";
return 0;
}
//用于创建 与指定的服务提供者进行绑定
SOCKET hServer;
hServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (hServer == INVALID_SOCKET)
{
cout << "创建套接字失败!\n";
closesocket(hServer);
WSACleanup();
return 0;
}
//绑定(bind函数)
sockaddr_in addrServer;
addrServer.sin_family = AF_INET;
addrServer.sin_port = htons(8000);
addrServer.sin_addr.s_addr = htonl(INADDR_ANY);
int nRet = bind(hServer, (LPSOCKADDR)&addrServer, sizeof(addrServer));
if (nRet == SOCKET_ERROR) //绑定地址 套接字:sockaddr结构指针:缓冲区长度
{
printf("邦定失败!\n");
closesocket(hServer);
WSACleanup();
return 0;
}
//监听
nRet = listen(hServer, 10);
if (nRet == SOCKET_ERROR)
{
cout << "监听失败";
closesocket(hServer);
WSACleanup();
return 0;
}
//接受来自客户端请求
SOCKET hClient;
sockaddr_in addrClient;
int nlen = sizeof(addrClient);
hClient = accept(hServer, (sockaddr *)&addrClient, &nlen);
if (hClient == INVALID_SOCKET)
{
cout << "错误";
closesocket(hServer);
WSACleanup();
return 0;
}
//接受客户端数据
char szbuf[sizeN];
while (true)
{
memset(szbuf, 0, sizeN);
nRet = recv(hClient, szbuf, sizeN, 0);
if (nRet == SOCKET_ERROR)
{
cout << "recv 错误";
closesocket(hClient);
closesocket(hServer);
WSACleanup();
return 0;
}
char sPrintbuf[sizeN];
sprintf_s(sPrintbuf, "IP:%s,接收的信息:%s\n", inet_ntoa(addrClient.sin_addr), szbuf);
cout << sPrintbuf;
//发送给客户端数据
if (strcmp(szbuf, "close") == 0)
{
nRet = send(hClient, "close", strlen("close"),0);
}
else
{
sprintf_s(sPrintbuf, "服务器已经接收到的消息,%s", szbuf);
nRet = send(hClient, sPrintbuf, strlen(sPrintbuf)+1, 0);
if (SOCKET_ERROR==nRet)
{
cout << "send 出错\n";
closesocket(hClient);
closesocket(hServer);
WSACleanup();
}
}
}
closesocket(hClient);
closesocket(hServer);
WSACleanup();
getchar();
getchar();
return 0;
}
客户端流程:
1,建立流式套接字
2,将套接字与主机连接
3,在套接字上读/写数据
4,关闭套接字,结束服务
代码:
// 服务器端.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#define sizeN 225
#include "winsock2.h" //WinSock2的头文件winsock2.h
#pragma comment(lib, "ws2_32.lib") //导入库文件ws2_32.lib,链接WinSock导入库
#include<iostream>
using namespace std;
int main()
{
WSADATA wsaData; //指向WASDATA结构体变量的指针
WORD wVersion = MAKEWORD(2, 2); //版本号
if (WSAStartup(wVersion, &wsaData) != 0) //加载WinSock动态链接库
{
cout << "加载winsock.dll失败!\n";
return 0;
}
//用于创建 与指定的服务提供者进行连接
SOCKET hClient;
hClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (hClient == INVALID_SOCKET)
{
cout << "创建套接字失败!\n";
closesocket(hClient);
WSACleanup();
return 0;
}
//连接(connect函数)
sockaddr_in addrClient;
addrClient.sin_family = AF_INET;
addrClient.sin_port = htons(8000);
addrClient.sin_addr.s_addr = inet_addr("127.0.0.1");
if (connect(hClient, (const sockaddr*)&addrClient, sizeof(addrClient)) < 0) //连接
{
cout << "连接失败\n";
WSACleanup();
return 0;
}
while (1)
{
int nRet;
char szbuf[sizeN];
cout << "发送消息:";
cin >> szbuf;
nRet = send(hClient, szbuf, strlen(szbuf) + 1, 0); //发送信息
if (SOCKET_ERROR == nRet)
{
cout << "send 出错\n";
closesocket(hClient);
WSACleanup();
}
nRet = recv(hClient, szbuf,sizeN, 0); //接收信息
if (nRet == SOCKET_ERROR)
{
cout << "recv 错误";
closesocket(hClient);
WSACleanup();
return 0;
}
cout << szbuf << endl<<endl;
}
closesocket(hClient);
WSACleanup();
getchar();
return 0;
}