使用C++基于windows平台下实现Tcp服务器端
main.cpp
#include <WinSock2.h>
#include <WS2tcpip.h>
#include <iostream>
using namespace std;
#pragma comment(lib, "ws2_32.lib")
int main() {
//初始化winsock2.2相关的动态库
WSADATA wd; // 获取socket相关信息
if(0 != WSAStartup(MAKEWORD(2, 2), &wd)) { //0 表示成功
cout << "WSAStartup error: " << WSAGetLastError() << endl;
return 0;
}
//1. 创建TCP socket 流式套接字
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(INVALID_SOCKET == s) {
cout << "socket error :" << WSAGetLastError() << endl;
return 0;
}
//2. 绑定socket到一个IP地址和端口
sockaddr_in addr; //不建议使用sockaddr 建议用sockaddr_in
addr.sin_family = AF_INET; // 地址族
addr.sin_port = htons(8888);//本地端口 转网络字节序
//addr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");//ip地址转网络字节序 inet_addr只能为ipv4转换 属于低版本 不建议用
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);//ip地址转网络字节序
int len = sizeof(sockaddr_in);
if(SOCKET_ERROR == bind(s, (sockaddr*)&addr, len)) {
cout << "bind error: "<< WSAGetLastError() <<endl;
return 0;
}
//3. 监听, 5 代表正在等待完成相应的TCP三次握手过程的队列长度
if(SOCKET_ERROR == listen(s, 5)) { // 根据电脑配置设定链接数
cout << "listen error:"<< WSAGetLastError() << endl;
return 0;
}
//4. 接受客户端请求,并且返回和客户端通讯的套接字
sockaddr_in addrClient; //保存客户端IP地址端口
memset(&addrClient, 0, sizeof(sockaddr_in));
len = sizeof(sockaddr_in);
SOCKET c = accept(s, (sockaddr*)& addrClient, &len); //成功返回套接字
if(INVALID_SOCKET == c) {
cout << "accept error:" << WSAGetLastError()<< endl;
return 0;
}
//5. 发送 接受消息
int ret = 0;
do {
//向刚连接的客户端发送数据, 不能用监听套接字,而应该用accept返回的套接字 c
char str[20] = "I am server!";
ret = send(c, str, strlen(str), 0);//把flag置0
//接受客户端的消息
char buf[64] = {'\0'};
char *address = new char;
ret = recv(c, buf, 64, 0); //把flag置 0
//cout << "recv" << inet_ntoa(addrClient.sin_addr) << ": " << buf << endl; //inet_ntoa 转换为IP字符串 inet_ntoa只能为ipv4转换 属于低版本 不建议用
cout << "recv : " << inet_ntop(AF_INET, (void*)&addrClient.sin_addr, address, sizeof(SOCKADDR_IN)) << ": " << buf << endl; //inet_ntoa 转换为IP字符串
} while(ret != SOCKET_ERROR && ret != 0); //对方关闭 返回0 , 错误返回 SOCKET_ERROR
//6. 关闭套接字
closesocket(s);
//清理winsock环境
WSACleanup();
return 0;
}