Client:
#include <stdio.h>
#include <winsock2.h>
#include <Windows.h>
#pragma warning(disable:4996)
#pragma comment(lib,"ws2_32.lib")
#define PORT 9898
int main(int argc, char * argv[])
{
//初始化网络环境
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("WSAStartup failed\n");
return -1;
}
// 初始化完成,创建一个TCP的socket
SOCKET sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sServer == INVALID_SOCKET)
{
printf("socket failed\n");
return -1;
}
//指定连接的服务端信息
SOCKADDR_IN addrServ;
addrServ.sin_family = AF_INET;
addrServ.sin_port = htons(PORT);
//客户端只需要连接指定的服务器地址,127.0.0.1是本机的回环地址
addrServ.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
// 服务器Bind 客户端是进行连接
//int ret = connect(sServer, (SOCKADDR*)&addrServ, sizeof(SOCKADDR));//开始连接
//if (SOCKET_ERROR == ret)
//{
// printf("socket connect failed\n");
// WSACleanup();
// closesocket(sServer);
// return -1;
//}
int ret = 0;
while (connect(sServer, (SOCKADDR*)&addrServ, sizeof(SOCKADDR)) < 0)
{
continue;
}
//连接成功后,就可以进行通信了
char szBuf[1024];
memset(szBuf, 0, sizeof(szBuf));
sprintf_s(szBuf, sizeof(szBuf), "Hello server");
//当服务端是recv的时候,客户端就需要send,若两端同时进行收发则会卡在这里,因为recv和send是阻塞的
while (1)
{
ret = send(sServer, szBuf, strlen(szBuf), 0);
if (SOCKET_ERROR == ret)
{
printf("socket send failed\n");
closesocket(sServer);
return -1;
}
ret = recv(sServer, szBuf, sizeof(szBuf), 0);
if (SOCKET_ERROR == ret)
{
printf("socket recv failed\n");
closesocket(sServer);
return -1;
}
printf("%s\n", szBuf);
Sleep(1000);
}
closesocket(sServer);
WSACleanup();
return 0;
}
Server:
#include <stdio.h>
#include <winsock2.h> // 必须包含windwos.h之前
#include <Windows.h>
#pragma comment(lib,"ws2_32.lib")
#define PORT 9898
DWORD WINAPI clientProc(LPARAM lparam)
{
SOCKET sockClient = (SOCKET)lparam;
char buf[1024];
while (TRUE)
{
memset(buf, 0, sizeof(buf));
// 接收客户端的一条数据
int ret = recv(sockClient, buf, sizeof(buf), 0);
//检查是否接收失败
if (SOCKET_ERROR == ret)
{
printf("socket recv failed\n");
closesocket(sockClient);
return -1;
}
// 0 代表客户端主动断开连接
if (ret == 0)
{
printf("client close connection\n");
closesocket(sockClient);
return -1;
}
// 发送数据
ret = send(sockClient, buf, strlen(buf), 0);
//检查是否发送失败
if (SOCKET_ERROR == ret)
{
printf("socket send failed\n");
closesocket(sockClient);
return -1;
}
}
closesocket(sockClient);
return 0;
}
bool InitNetEnv()
{
// 进行网络环境的初始化操作
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
{
printf("WSAStartup failed\n");
return false;
}
return true;
}
int main(int argc, char * argv[])
{
if (!InitNetEnv())
{
return -1;
}
// 初始化完成,创建一个TCP的socket
SOCKET sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
//检查是否创建失败
if (sServer == INVALID_SOCKET)
{
printf("socket failed\n");
return -1;
}
printf("Create socket OK\n");
//进行绑定操作
SOCKADDR_IN addrServ;
addrServ.sin_family = AF_INET; // 协议簇为IPV4的
addrServ.sin_port = htons(PORT); // 端口 因为本机是小端模式,网络是大端模式,调用htons把本机字节序转为网络字节序
addrServ.sin_addr.S_un.S_addr = INADDR_ANY; // ip地址,INADDR_ANY表示绑定电脑上所有网卡IP
//完成绑定操作
int ret = bind(sServer, (sockaddr *)&addrServ, sizeof(sockaddr));
//检查绑定是否成功
if (SOCKET_ERROR == ret)
{
printf("socket bind failed\n");
WSACleanup(); // 释放网络环境
closesocket(sServer); // 关闭网络连接
return -1;
}
printf("socket bind OK\n");
// 绑定成功,进行监听
ret = listen(sServer, 10);
//检查是否监听成功
if (SOCKET_ERROR == ret)
{
printf("socket listen failed\n");
WSACleanup();
closesocket(sServer);
return -1;
}
printf("socket listen OK\n");
// 监听成功
sockaddr_in addrClient; // 用于保存客户端的网络节点的信息
int addrClientLen = sizeof(sockaddr_in);
while (TRUE)
{
//新建一个socket,用于客户端
SOCKET *sClient = new SOCKET;
//等待客户端的连接
*sClient = accept(sServer, (sockaddr*)&addrClient, &addrClientLen);
if (INVALID_SOCKET == *sClient)
{
printf("socket accept failed\n");
WSACleanup();
closesocket(sServer);
delete sClient;
return -1;
}
//创建线程为客户端做数据收发
CreateThread(0, 0, (LPTHREAD_START_ROUTINE)clientProc, (LPVOID)*sClient, 0, 0);
}
closesocket(sServer);
WSACleanup();
return 0;
}