TCP server 代码

本代码为tcp服务器端的C++代码,代码实现的功能是接受客户端的请求,当客户端发送来的信息时,回复“OK”字符串。

服务器端工作原理:

服务器首先开启一个socket,并一直监听这个socket。这时,程序在accept处阻塞。当有请求过来时,就会accept成功。accept成功后会返回一个新的socket,这个新的socket负责服务器与这个客户端的通讯。这时主线程新建一个子线程,并将新的socket传给这个子线程,在这个子线程中进行服务器与这个客户端的通讯工作。

下面是服务器端代码:

/*Server*/

#include <stdio.h>
#include <WinSock2.h>
#include <process.h>
#include <WS2tcpip.h>

#pragma comment(lib, "ws2_32.lib")

int InitWinSocket()
{
	WORD wVersionRequested;
	WSADATA wsaData;
	int err;

	wVersionRequested = MAKEWORD(1, 1);//第一个参数为低位字节;第二个参数为高位字节

	err = WSAStartup(wVersionRequested, &wsaData);//对winsock DLL(动态链接库文件)进行初始化,协商Winsock的版本支持,并分配必要的资源
	if (err != 0)
	{
		return -1;
	}

	if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)//LOBYTE()取得16进制数最低位;HIBYTE()取得16进制数最高(最左边)那个字节的内容
	{
		WSACleanup();
		return -1;
	}

	return 0;
}

unsigned _stdcall WorkProc(LPVOID args)
{
	SOCKET* workSock = (SOCKET*)args;
	char buf[64];
	while (1)
	{
		/*收到请求*/
		memset(buf, 0, sizeof(buf));
		recv(*workSock, buf, sizeof(buf), 0);
		printf("recv: %s\n", buf);

		/*回复请求*/
		memset(buf, 0, sizeof(buf));
		sprintf_s(buf, "%s", "OK");
		send(*workSock, buf, strlen(buf), 0);
	}
	closesocket(*workSock);
}

int main()
{
	/*初始化 Windows Socket*/
	if (InitWinSocket() != 0)
	{
		printf("Init Windows Sock Failed!\n");
		return -1;
	}

	printf("Server:\n");
	
	SOCKET sock;
	sockaddr_in server;
	sockaddr_in client;
	int addr_len = sizeof(SOCKADDR);

	/*创建socket*/
	sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (sock < 0)
	{
		printf("create socket failed!\n");
		return -1;
	}

	/*对socket进行一些设置,这里是端口复用设置*/
	int opt = 1;
	socklen_t optlen = sizeof(opt);
	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, optlen) < 0)
	{
		printf("set sock opt failed!\n");
		return -1;
	}

	/*设置服务器ip和端口*/
	server.sin_family = AF_INET;
	server.sin_port = htons(9555);
	server.sin_addr.s_addr = 0;

	/*绑定服务器地址和socket*/
	if (bind(sock, (sockaddr*)&server, addr_len) < 0)
	{
		printf("binding socket failed!\n");
		return -1;
	}

	/*开启监听*/
	listen(sock, 16);//第二个参数是未完成队列的大小

	while (1)
	{
		SOCKET workSock = accept(sock, (SOCKADDR*)&client, &addr_len);
		if (workSock < 0)
		{
			return -1;
		}

		/*新建一个线程,把与该客户端通讯的工作放到这个线程里*/
		HANDLE h = (HANDLE)_beginthreadex(NULL, 0, WorkProc, (void*)&workSock, NULL, NULL);
		
	}

	WSACleanup();
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值