在VS中实现C的Socket通信

一、在一个解决方案下创建两个项目及其文件

项目分别是客户端和服务器,通过这两个项目实现客户端和服务器之间的通信

 

二、编写源文件以及头文件

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;
}

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值