Windows下的Socket编程C语言

Windows下纯C代码socket编程源码演示

同一主机或者用一局域网之间进行通信。

服务端代码:

#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS 


#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<WinSock2.h>//头文件
#pragma comment(lib,"Ws2_32.lib")//网络库
int main(){
	WORD wdversion = MAKEWORD(2, 2);//关于内存 需要的版本  wdversion转换为二进制高字节装副版本号 低字节装主版本号
	// int *a= *(char*(&wdversion));
	// int *b-*(char*(&wdversion+1));
	WSADATA wdsockmsg;     //可以用指针 要申请堆空间 并且释放 在这里栈空间已经足够
	/*LPWSADATA lpw=malloc(sizeof(WSADATA));
	......free();  (使用堆内存)*/
	int nres = WSAStartup(wdversion, &wdsockmsg);//打开网络库

	if (nres != 0){
		switch (nres)
		{
		case WSASYSNOTREADY:
			printf("重启一下电脑试试");
			break;
		case WSAVERNOTSUPPORTED:
			printf("请更新网络库");
			break;
		case WSAEINPROGRESS:
			printf("请重新启动");
			break;
		case WSAEPROCLIM:
			printf("请关掉不必要的软件");
			break;  //错误代码的解释
		}
		return 0;
	}



	if (HIBYTE(wdsockmsg.wVersion) != 2 || LOBYTE(wdsockmsg.wVersion) != 2)//校验版本
	{
		//版本不对
		WSACleanup();//清理关闭网络库
		return 0;
	}
	
	SOCKET socketsever = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //操作接口 调用协议通信 第三个参数可以为0默认参数值 此处默认为tcp
	//第一个参数ip地址类型 第二个套接字类型 第三个传输协议

	if (socketsever == INVALID_SOCKET)
	{
		int error = WSAGetLastError();  //错误码
		WSACleanup();   //清理网络库
		return 0;
	}
	
	struct sockaddr_in sever;
	sever.sin_family = AF_INET;//ipv4
	sever.sin_port = htons(12345);
	sever.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

	bind(socketsever, (const struct sockaddr*)&sever, sizeof(sever));//服务器端要用 bind() 函数将套接字与特定的 IP 地址和端口绑定起来
	/*bind第一个参数是socket变量 第二个参数为结构体变量addr里面有端口号 ip地址 第三个变量为addr变量的大小*//*(返回值正确为0 错误返回错误码)*/


	listen(socketsever, SOMAXCONN);//开始监听

	if (listen(socketsever, SOMAXCONN) == SOCKET_ERROR)
	{
		int error2 = WSAGetLastError();//获得错误码
		closesocket(socketsever); //关闭网络连接
		WSACleanup();//关闭网络库	
		return 0;
	}


	struct sockaddr_in client;//创建客户端信息 系统自动填写
	int len = sizeof(client);
	SOCKET socketclient = accept(socketsever, (struct sockaddr*)&client, &len); //返回一个socket 客户端的socket 不想知道客户端的socket时把第二个人参数置为NULL

	if (socketsever == INVALID_SOCKET)//invalid_socket 表示socket创建无效的返回值  
	{
		printf("客户端连接失败\n");
		int error3 = WSAGetLastError();  //错误码
		closesocket(socketsever); //关闭网络连接
		WSACleanup();//关闭网络库	
		return 0;
	}



	printf("客户端连接成功\n");
	Sleep(100000);

	
	char buf1[1024];
	scanf("%s", buf1);
	send(socketclient, buf1, sizeof(buf1), 0);//创建发送函数 参数与接受类似 若无错误返回发送的总字节数	
	int res2 = send(socketclient, buf1, strlen(buf1), 0);
	if (res2 == SOCKET_ERROR)
	{
		int error5 = WSAGetLastError();
		printf("请根据错误码解决.\n");
		return 0;
	}

	char buf2[1000] = { 0 };
	recv(socketclient, buf2, 1000, 0);
	printf("我收到的是:%s\n", buf2);

	closesocket(socketclient);//关闭网络连接(客户端)
	closesocket(socketsever); //关闭网络连接(服务端)
	WSACleanup();//关闭网络库
	system("pause");

}

客户端代码

#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS 
#include<stdio.h>
#include<stdlib.h>
#include<WinSock2.h>//头文件
#include<string.h>
#pragma comment(lib,"Ws2_32.lib")//网络库
int main(){
	
	WORD wdversion = MAKEWORD(2, 2);//关于内存 需要的版本  wdversion转换为二进制高字节装副版本号 低字节装主版本号
	// int *a= *(char*(&wdversion));
	// int *b-*(char*(&wdversion+1));
	WSADATA wdsockmsg;     //可以用指针 要申请堆空间 并且释放 在这里栈空间已经足够
	/*LPWSADATA lpw=malloc(sizeof(WSADATA));
	......free();  (使用堆内存)*/
	int nres = WSAStartup(wdversion, &wdsockmsg);//打开网络库
	if (nres != 0){
		switch (nres)
		{
		case WSASYSNOTREADY:
			printf("重启一下电脑试试");
			break;
		case WSAVERNOTSUPPORTED:
			printf("请更新网络库");
			break;
		case WSAEINPROGRESS:
			printf("请重新启动");
			break;
		case WSAEPROCLIM:
			printf("请关掉不必要的软件");
			break;  //错误代码的解释
		}
		return 0;
	}


	if (HIBYTE(wdsockmsg.wVersion) != 2 || LOBYTE(wdsockmsg.wVersion) != 2)//校验版本
	{
		//版本不对
		WSACleanup();//清理关闭网络库
		return 0;
	}

	SOCKET socketsever = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //操作接口 调用协议通信 第三个参数可以为0默认参数值 此处默认为tcp
	//第一个参数ip地址类型 第二个套接字类型 第三个传输协议

	if (socketsever == INVALID_SOCKET)
	{
		int error = WSAGetLastError;  //错误码
		WSACleanup();   //清理网络库
		return 0;
	}

	struct sockaddr_in sever;
	sever.sin_family = AF_INET;//ipv4
	sever.sin_port = htons(12345);
	sever.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");

	connect(socketsever, ( struct sockaddr*)&sever, sizeof(sever));
	int res1 = connect(socketsever, (const struct sockaddr*)&sever, sizeof(sever));
	if (res1 == SOCKET_ERROR)
	{         
		int error = WSAGetLastError;//连接失败出错了 找出错误码进行改正
		closesocket(socketsever); //关闭网络连接(服务端)
		WSACleanup();//关闭网络库
		return 0;
	}


	char buf[1500] = { 0 };
	int res = recv(socketsever, buf, 1024, 0);//参数一指接受数据的来源socket,参数二指接受到的字符数组 最大长度一次一般为1500,参数三指需要接受的字符数组的长度,参数四设为0;
	if (res == 0)
	{
		printf("连接中断,客户端下线\n");
	}
	else if (res == SOCKET_ERROR)
	{
		int error4 = WSAGetLastError;//出错了 找出错误码进行改正
		return 0;
	}
	else
	{
		printf("%d  %s\n", res, buf);
	}

	char buf2[1024] = { 0 };
	gets(buf2);
	for (int i = 0; i < 3; i++)
	{	
		send(socketsever, buf2, 1024, 0);
	}

	closesocket(socketsever); //关闭网络连接(服务端)d
	WSACleanup();//关闭网络库
	system("pause");

	return 0;
}
  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值