您的位置:首页 > 编程语言 > C语言/C++

C++ 简单Socket服务端代码实现

2018-03-21 15:53 585 查看
原文地址:点击打开链接
代码如下:// Server.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <winsock2.h>
#pragma comment(lib,"Ws2_32.lib")

int _tmain(int argc, _TCHAR* argv[])
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
{
printf("load socket version error!\n");
return 0;
}

SOCKET sockListen = socket(AF_INET,SOCK_STREAM,0);
if (sockListen == INVALID_SOCKET)
{
printf("create socket error!\n");
return 0;
}

sockaddr_in srvAddr;
srvAddr.sin_family = AF_INET;
srvAddr.sin_port = htons(80);
srvAddr.sin_addr.S_un.S_addr = INADDR_ANY;

if (bind(sockListen,(sockaddr*)&srvAddr,sizeof(srvAddr)) == INVALID_SOCKET)
{
printf("bind error\n");
return 0;
}

if(listen(sockListen,10) == INVALID_SOCKET)
{
printf("listen error!\n");
return 0;
}

SOCKET sockMsg;
sockaddr_in remoteAddr;
int nLen = sizeof(remoteAddr);

sockMsg = accept(sockListen,(sockaddr *)&remoteAddr,&nLen);
if (sockMsg == INVALID_SOCKET)
{
printf("accept error!\n");
return 0;
}

char recvBuf[255];
memset(recvBuf,1,sizeof(recvBuf));
while (true)
{
recv(sockMsg,recvBuf,sizeof(recvBuf),0);
printf("%s\n",recvBuf);

const char* sendBuf = "hello Client!";
send(sockMsg,sendBuf,strlen(sendBuf),0);
}

closesocket(sockMsg);
closesocket(sockListen);
WSACleanup();

return 0;
}

拆分解释:        WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
{
printf("load socket version error!\n");
return 0;
}加载套接字版本库。
WSADATA:用来存储 WSAStartup 函数调用后返回的 Windows Sockets 数据;
WSAStartup 函数:WSA的启用命令;
WSA:Windows Socket Asynchronous  Windows异步套接字

SOCKET sockListen = socket(AF_INET,SOCK_STREAM,0);
if (sockListen == INVALID_SOCKET)
{
printf("create socket error!\n");
return 0;
}
创建套接字。
SOCKET socket(int af, int type, int protocol);
int af: 指定地址族;
int type: 指定socket类型,常用SOCKET_STREAM,SOCK_DGRAM;
int protocol: 指定协议,为 0 时,自动选择与第二个参数匹配的协议,一般默认为 0;

sockaddr_in srvAddr;
srvAddr.sin_family = AF_INET;
srvAddr.sin_port = htons(80);
srvAddr.sin_addr.S_un.S_addr = INADDR_ANY;

if (bind(sockListen,(sockaddr*)&srvAddr,sizeof(srvAddr)) == INVALID_SOCKET)
{
printf("bind error\n");
return 0;
}绑定 IP 和 端口。
int bind(SOCKET s, const struct sockaddr FAR* name, int namelen);
SOCKET s: 描述一个未绑定的套接字的描述符,即不可以重复绑定;
const struct sockaddr FAR* name: 从 sockaddr 结构中分配得到套接字的地址;
int namelen: name 参数中值的长度;
srvAddr.sin_family = AF_INET: 创建套接字时,用该字段指定地址家族,对于 TCP/IP 协议,必须设置为 AF_INET ;
srvAddr.sin_port = htons(80): sin_port设置端口号;
srvAddr.sin_addr.S_un.S_addr = INADDR_ANY: 设置IP

if(listen(sockListen,10) == INVALID_SOCKET)
{
printf("listen error!\n");
return 0;
}开启监听。
int listen(SOCKET s, int blacklog);
SOCKET s: 描述一个绑定的、没有连接的套接字的描述符;
int blacklog: 等待连接的队列的最大长度;

  SOCKET sockMsg;
sockaddr_in remoteAddr;
int nLen = sizeof(remoteAddr);

sockMsg = accept(sockListen,(sockaddr *)&remoteAddr,&nLen);
if (sockMsg == INVALID_SOCKET)
{
printf("accept error!\n");
return 0;
}数据接收。
SOCKET sockMsg: 通讯套接字;
sockaddr_in remoteAddr: 远程连接地址;
SOCKET accept(_in SOCKET s, _out struct sockaddr* addr, _inout int *addrlen);
in SOCKET s: 描述一个套接字在监听函数中被置于监听状态的描述符;

_out struct sockaddr* addr: 一个可选的指针,用来接收连接实体的地址;

_inout int *addrlen: 一个可选的指向一个整数的指针,它包含了 addr 参数所指向的结构的长度;

  char recvBuf[255];
memset(recvBuf,1,sizeof(recvBuf));
while (true)
{
recv(sockMsg,recvBuf,sizeof(recvBuf),0);
printf("%s\n",recvBuf);

const char* sendBuf = "hello Client!";
send(sockMsg,sendBuf,strlen(sendBuf),0);
}
数据接收和发送。
memset(): 此函数为新申请的内存做初始化工作;
int recv(SOCKET s, char FAR *buf, int len, int flags); 返回接收到的字节数
SOCKET s: 连接套接字描述符;

char FAR *buf: 用于输入数据的缓冲区;
int len: buf参数的长度;

int flags: 标记指定调用的方式,一般为 0;

int send(SOCKET s, char FAR *buf, int len, int flags);如果没有发生错误,函数将返回发送的字节数

SOCKET s: 连接套接字描述符;

char FAR *buf: 包含要传输的数据的缓冲区;
int len: buf参数的长度;

int flags: 标记指定调用的方式,一般为 0;

        closesocket(sockMsg);
closesocket(sockListen);
WSACleanup();释放资源。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: