Winsock编程——TCP通信入门代码示例

设计

最基本的TCP通信示例。连接建立成功后,客户端发送Tan Kuku desu(唐可可です)时,服务端返回Shibuya Kanon desu!(澁谷かのんです!)。

Server和Client的共用类

为了方便后续代码编写,这里封装一个CInitSock类来管理Winsock库。

#include <WinSock2.h>
#pragma comment(lib, "WS2_32")
class CInitSock
{
	public:
		CInitSock(BYTE minorVer = 2, BYTE majorVer = 2)
		{
			WSADATA wsaData;
			WORD sockVersion = MAKEWORD(minorVer, majorVer);
			if (::WSAStartup(sockVersion, &wsaData)!=0)
			{
				exit(0);
			}
		}
		~CInitSock()
		{
			::WSACleanup();
		}
};

TCP Server

#include <stdio.h>
#include "CInitSock.h"

CInitSock initSock;
int main()
{
	// 创建套接字,返回套接字句柄 sListen
    SOCKET sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sListen == INVALID_SOCKET)
	{
		printf("Failed socket()\n");
		return 0;
	}

	// 填充sockaddr_in结构
	sockaddr_in	sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(8889);
	sin.sin_addr.S_un.S_addr = INADDR_ANY;

	// 绑定这个套接字到一个本地地址
	if (::bind(sListen, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
	{
		printf("Failed bind()\n");
		return 0;
	}

	// 进入监听状态
	if (::listen(sListen, 2) == SOCKET_ERROR)
	{
		printf("Failed listen()\n");
		return 0;
	}

	// 循环接受客户端的连接请求
	sockaddr_in remoteAddr;
	int nAddrLen = sizeof(remoteAddr);
	SOCKET sClient;
	//设置回复内容
	char szText[] = "Shibuya Kanon desu!\n";
	while (TRUE)
	{
		// 接收新连接
		sClient = ::accept(sListen, (SOCKADDR*)&remoteAddr, &nAddrLen);
		if (sClient == INVALID_SOCKET)
		{
			printf("Failed accept()");
			continue;
		}
		printf("接收到一个来自 %s 的连接\n", inet_ntoa(remoteAddr.sin_addr));

		// 开始收发数据
		// 从客户端接收数据
		char buff[256];
		int nRecv = ::recv(sClient, buff, 256, 0);
		if (nRecv > 0)
		{
			buff[nRecv] = '\0';
			printf("接收到数据:%s\n", buff);
			if (strcmp(buff, "Tan Kuku desu") == 0)
			{		
				// 向客户端发送数据
				::send(sClient, szText, strlen(szText), 0);
			}
		}
		// 关闭套接字 sClient
		printf("与 %s 的连接已断开\n", inet_ntoa(remoteAddr.sin_addr));
		::closesocket(sClient);
	}
	// 关闭监听套接字 sListen,服务结束
	::closesocket(sListen);
	return 0;
}

TCP Client

#include <stdio.h>
#include "CInitSock.h"

CInitSock initSock;
int main()
{
	// 创建套接字
	SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (s == INVALID_SOCKET)
	{
		printf("Failed socker()\n");
		return 0;
	}

	// 填写服务端信息
	sockaddr_in servAddr;
	servAddr.sin_family = AF_INET;
	servAddr.sin_port = htons(8889);
	servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	// 发起连接
	if (::connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1)
	{
		printf("Failed connect()\n");
		return 0;
	}

	// 发送数据
	 char szText[256];
	 scanf("%[^\n]", szText);
	 szText[strlen(szText)] = '\0';
	 ::send(s, szText, strlen(szText), 0);

	// 接收数据
	char buff[256];
	int nRecv = ::recv(s, buff, 256, 0);
	if (nRecv > 0)
	{
		buff[nRecv] = '\0';
		printf("接收到数据:%s\n", buff);
	}
	// 关闭套接字,结束TCP对话
	::closesocket(s);
	return 0;
}

效果截图

本文采用 CC BY-NC-SA 4.0 协议

评论

  1. one
    Windows Edge
    3月前
    2022-3-30 10:56:31

    请问下这个mac风格的代码块怎么实现的,百度了好久都没搞定

    • 博主
      one
      Macintosh Safari
      3月前
      2022-3-30 13:19:43

      Argon主题自带的代码块样式

      • one
        涼風桜雨
        Windows Edge
        3月前
        2022-3-30 14:33:38

        找到选项了,谢谢

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇