一、在一个解决方案下创建两个项目及其文件
项目分别是客户端和服务器,通过这两个项目实现客户端和服务器之间的通信
二、编写源文件以及头文件
2.1服务器
2.1.1头文件
#ifndef _TCPSOCKET_H_
#define _TCPSOCKET_H_
#include<WinSock2.h> //windows平台的网络库头文件
#pragma comment(lib,"ws2_32.lib") //库文件
#include<stdbool.h>
#include<stdio.h>
#define PORT 5005
#define err(errMsg) printf("[line:%d]%s failed code %d",__LINE__,errMsg, WSAGetLastError())
//打开网络库
bool init_Socket();
//关闭网络库
bool close_Socket();
//创建服务端socket
SOCKET createServerSocket();
#endif // !_TCPSOCKET_H_
这里的端口号以及自定义的宏定义err可以根据需求自己修改
2.1.2打开网络库和修改网络库的代码
#include"TcpSocket.h"
bool init_Socket()
{
//was windows socket async windows异步套接字
//param1:请求的socket版本 param2:传出参数
WSADATA wsadata;
if (0 != WSAStartup(MAKEWORD(2, 2), &wsadata))
{
err("WSAStartup");
return false;
}
return true;
}
bool close_Socket()
{
if (0 != WSACleanup())
{
err("WSACleanUp");
return false;
}
return true;
}
SOCKET createServerSocket()
{
//1,创建空Socket
//param1:af 地址协议 ipv4 ipv6
//param2:type 传输协议类型 流式套接字 数据报套接字
//param3:protocol 使用具体的某个传输协议
SOCKET fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (fd == INVALID_SOCKET) {
err("socket");
return INVALID_SOCKET;
}
struct sockaddr_in addr;
addr.sin_family = AF_INET; //和创建socket时的必须一样
//htons 将本地转换成网络(大端)
addr.sin_port = htons(PORT); //大端存储 和 小端存储
addr.sin_addr.S_un.S_addr = ADDR_ANY; //inet_addr("127.0.0.1");
if(INVALID_SOCKET == bind(fd, &addr, sizeof(addr)))
{
err("bind");
return false;
}
//3,监听
listen(fd, 10);
return fd;
}
其中 ADDR_ANY即INADDR_ANY,就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。也就是表示本机的所有IP,因为有些机子不止一块网卡,多网卡的情况下,这个就表示所有网卡ip地址的意思。
2.1.3实现操作部分代码
#include"../TcpSocket/TcpSocket.h"
int main() {
init_Socket();
SOCKET serfd = createServerSocket();
printf("wait client connect...\n");
//如果有客户端请求连接
SOCKET clifd = accept(serfd, NULL, NULL);
if (INVALID_SOCKET == clifd) {
err("accept");
}
//可以和客户端进行通信
char recvbuf[BUFSIZ] = {0}; //这两个必须清空置零
char sendbuf[BUFSIZ] = {0};
while (true)
{
//recv从指定的socket接受消息
if (0 < recv(clifd, recvbuf, BUFSIZ, 0)) {
printf("recv:%s\n", recvbuf);
}
//发送消息
printf("send>");
memset(sendbuf, 0, sizeof(sendbuf));
gets_s(sendbuf, BUFSIZ);
if (SOCKET_ERROR == send(clifd, sendbuf, strlen(sendbuf), 0)) {
err("send");
}
}
closesocket(clifd);
closesocket(serfd);
close_Socket();
printf("server---------end-----\n");
getchar();
return 0;
}
2.2客户端
2.2.1头文件
#ifndef _TCPSOCKET_H_
#define _TCPSOCKET_H_
#include<WinSock2.h> //windows平台的网络库头文件
#pragma comment(lib,"ws2_32.lib") //库文件
#include<stdbool.h>
#include<stdio.h>
#define PORT 5005
#define err(errMsg) printf("[line:%d]%s failed code %d",__LINE__,errMsg, WSAGetLastError())
//打开网络库
bool init_Socket();
//关闭网络库
bool close_Socket();
//创建客户端socket
SOCKET createClientSocket(const char *ip);
#endif // !_TCPSOCKET_H_
2.2.2打开网络库和修改网络库的代码
#include"CTcpSocket.h"
bool init_Socket()
{
//was windows socket async windows异步套接字
//param1:请求的socket版本 param2:传出参数
WSADATA wsadata;
if (0 != WSAStartup(MAKEWORD(2, 2), &wsadata))
{
err("WSAStartup");
return false;
}
return true;
}
bool close_Socket()
{
if (0 != WSACleanup())
{
err("WSACleanUp");
return false;
}
return true;
}
SOCKET createClientSocket(const char *ip)
{
//1,创建空Socket
//param1:af 地址协议 ipv4 ipv6
//param2:type 传输协议类型 流式套接字 数据报套接字
//param3:protocol 使用具体的某个传输协议
SOCKET fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (fd == INVALID_SOCKET) {
err("socket");
return INVALID_SOCKET;
}
struct sockaddr_in addr;
addr.sin_family = AF_INET; //和创建socket时的必须一样
//htons 将本地转换成网络(大端)
addr.sin_port = htons(PORT); //大端存储 和 小端存储
addr.sin_addr.S_un.S_addr = inet_addr(ip);
if(INVALID_SOCKET == connect(fd, (struct sockaddr*)&addr, sizeof(addr)))
{
err("connect");
return false;
}
return fd;
}
此部分代码与服务器部分的基本一致,只修改了创建客户端服务器通过传参来实现
2.2.3实现操作部分代码
#include"../TcpSocket/CTcpSocket.h"
int main() {
init_Socket();
SOCKET fd = createClientSocket("127.0.0.1");//传入的ip需要修改成本机的IP
char recvbuf[BUFSIZ] = {0};
char sendbuf[BUFSIZ] = {0};
while (true)
{
//发送消息
printf("send>");
gets_s(sendbuf, BUFSIZ);
if (SOCKET_ERROR == send(fd, sendbuf, strlen(sendbuf), 0)) {
err("send");
}
//recv从指定的socket接受消息
if (0 < recv(fd, recvbuf, BUFSIZ, 0)) {
printf("recv:%s\n", recvbuf);
memset(sendbuf,0,sizeof(sendbuf));
}
}
closesocket(fd);
close_Socket();
printf("client------end--------\n");
getchar();
return 0;
}