C++ SOCKET函数注释及示例代码

函数简介:

// 创建套接字

    // @param   af      通信区域,AF_UNIXAF_INET(国际网区域)、AF_NS等,DOSWINDOWS仅支持AF_INET

    // @param   type    套接字类型,SOCK_STREAMTCP流式套接字,面向连接可靠的数据传输,可控制流量,数据长度无限制)、SOCK_DGRAM(数据包式套接字,无连接服务,数据包以独立包形式发送)、SOCK_RAW(原始式套接字,允许对较低层协议IPICMP等直接访问)

    // @param   protocol协议,0为默认连接模式

    // @return  套接字号

    SOCKET PASCAL FAR socket(int af, int type, int protocol)

     

    // 绑定套接字地址与套接字号

    // @param   s       套接字号,由socket函数返回

    // @param   name    本地地址

    // @param   namelen     name的长度

    // @return  0绑定成功,SOCKET_ERROR绑定失败

    int PASCAL FAR bind(SOCKET s, const struct sockaddr FAR * name, int namelen)

     

    // 监听连接

    // @param   s       套接字号,由socket函数返回

    // @paaram  backlog请求连接队列的最大长度,用于限制排队请求的个数

    // @return  0监听成功,SOCKET_ERROR监听失败

    int PASCAL FAR listen(SOCKET s, int backlog)

     

    // 建立连接

    // @param   s       本地套接字号,由socket函数返回

    // @param   name    对方套接字地址

    // @param   namelen对方套接字地址长度

    // @return  0建立成功,SOCKET_ERROR建立失败

    int PASCAL FAR connect(SOCKET s, const struct sockaddr FAR * name, int namelen)

     

    // 接受连接

    // @param   s       本地套接字号,由socket函数返回

    // @param   addr    客户端套接字地址

    // @param   addrlen客户端套接字地址长度

    // @return  接受套接字,用于向客户端发送数据,INVALID_SOCKET接受失败

    SOCKET PASCAL FAR accept(SOCKET s, struct socaddrFAR * addr, int FAR * addrlen)

     

     

    // 数据发送

    // @param   s       本地套接字号,由socket函数返回

    // @param   buf     发送的数据缓冲区指针

    // @param   len     发送的数据长度

    // @param   flags   传输控制方式,是否发送带外数据

    // @return  发送的字节数,SOCKET_ERROR发送失败

    int PASCAL FAR send(SOCKET s, const char FAR * buf, int len, int flags)

     

    // 数据接收

    // @param   s       通信套接字号

    // @param   buf     接收数据缓冲区

    // @param   len     接收数据长度

    // @param   flags   是否接收带外数据

    // @return  接收的字节数,0 连接已关闭,SOCKET_ERROR接收失败

    int PASCAL FAR recv(SOCKET s, char FAR * buf, int len, int flags)

     

    // 套接字状态检测

    // @param   readfds     做读检测的套接字描述符结合的指针

    // @param   writefds    做写监测的套接字描述符集合的指针

    // @param   exceptfds   做是否出错的套接字描述符结合的指针

    // @param   timeout     该函数等待的最大时间,NULL为阻塞操作

    // @return  返回fd_set中的套接字描述符的总数目,SOCKET_ERROR检测失败

    int PASCAL FAR select(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR * timeout)

     

    // 关闭套接字

    // @param   s   要关闭的套接字

    // @return  0关闭成功,SOCKET_ERROR关闭失败

    BOOL PASCAL FAR closesocket(SOCKET s)

 

    // 设置套接口

    // @param   sockfd  标识一个套接口的描述字

    // @param   level   选项定义的层次

    // @param   optname 需设置的选项

    // @param   optval  选项值指针

    // @param   optlen  选项值长度

    // @return  0设置成功,SOCKET_ERROR设置套接口错误

    /*

        level     SOL_SOCKET  (基本套接口)

                    IPPROTO_TCP (TCP套接口)

                    IPPROTO_IP  (IPV4套接口)

                    IPPROTO_IPV6(IPV6套接口)

        optname   --------------------SOL_SOCKET--------------------------

                    SO_BROADCAST(BOOL, 是否允许发送广播消息,适用于UDP)

                    SO_DEBUG    (BOOL, 是否允许记录调试信息)

                    SO_DONTROUTE(BOOL, 是否禁止查找路由)

                    SO_KEEPALIVE(BOOL, 是否保持连接,主要用于对方主机的活动检测)

                    SO_OOBINLINE(BOOL, 是否在常规数据流中接收带外数据)

                    SO_REUSEADDR(BOOL, 是否允许重用本地地址和端口,主要用于关闭后需要重用该socket)

                    SO_EXCLUSIVEADDRUSE(BOOL, 是否独占模式使用端口,主要用于防止程序被监听)

                    SO_ACCEPTCONN(BOOL,套接口在监听)

                    TCP_NODELAY  (BOOL 禁止发送合并的Nagle算法)

                    SO_DONTLINER(BOOL, 是否有未发送数据时阻塞关闭操作)

                    SO_LINGER   (struct linger FAR* 如关闭时有未发送数据,则延迟关闭,SO_DONTLINER)

                    SO_RCVBUF   (int, 接收缓冲区大小,主要用于较大包的接收,0,不会从socket缓冲区拷贝到系统缓冲区)

                    SO_SNDBUF   (int, 发送缓冲区大小,主要用于较大包的发送,0,不会从系统缓冲区拷贝到socket缓冲区)

                    SO_RCVLOWAT (int,接收缓冲区下限,缺省1)

                    SO_SNDLOWAT (int,发送缓冲区下限,TCP缺省2048)

                    SO_RCVTIMEO(struct timeval, 接收超时)

                    SO_SNDTIMEO(struct timeval, 发送超时)

                    SO_ERROR    (int, 获取错误状态并清除)

                    SO_TYPE     (int, 套接口类型)

                    SO_BSDCOMPAT(int,BSD系统兼容)

                    IP_OPTIONS IP头中设置选项。

        参考:http://blog.csdn.net/chary8088/article/details/2486377

        示例:

            BOOL bOn = TRUE;

            setsockopt(s, SOL_SOCKET,SO_REUSEADDR, (const char* )&bOn, sizeof(BOOL));

            int nTimeout = 1000;

            setsockopt(s, SOL_SOCKET,SO_SNDTIMEO, (char*)&nTimeout, sizeof(int));

    */

    int setsockopt(int sockfd,int level, int optname,const void *optval, socklen_t optlen)



服务端示例代码:

#include "stdafx.h"
#include <stdio.h>
#include <Winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "mswsock.lib")

int _tmain(int argc, _TCHAR* argv[])
{
	//加载释放winsock库
	WSADATA wsaData;
	if(WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
	{
		printf("%s\n", "Load WinSock Error.");
		return 0;
	}
	if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) 
	{
		WSACleanup( );
		return 0;
	}

	//创建套接字
	SOCKET svrSocket = socket(AF_INET, SOCK_STREAM, 0);

	//绑定套接字,配置监听地址和端口
	SOCKADDR_IN svrAddr;
	ZeroMemory((char*)&svrAddr, sizeof(svrAddr));	
	svrAddr.sin_family = AF_INET;						//国际网区域
	svrAddr.sin_port = htons(6000);						//监听端口
	svrAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);	//有IP

	if(bind(svrSocket, (SOCKADDR*)&svrAddr, sizeof(SOCKADDR)) == SOCKET_ERROR)
	{
		printf("Bind Socket Error:%d\n", WSAGetLastError());
		return 0;
	}

	//监听
	if(listen(svrSocket, 5) == SOCKET_ERROR)//最大连接数5个
	{
		printf("Start Listen Error:%d\n", WSAGetLastError());
		return 0;
	}
	printf("Start Listen Succ...\n");

	//接收套接字
	SOCKADDR_IN clientAddr;
	SOCKET connSocket;
	int length = sizeof(SOCKADDR);
	char cExist = ' ';
	while(cExist != 'q')
	{
		//接收连接		
		if((connSocket = accept(svrSocket, (SOCKADDR*)&clientAddr, &length)) == INVALID_SOCKET)
		{
			printf("Accept Error:%d\n", WSAGetLastError());
			return 0;
		}
		

		//发送连接消息
		char sendBuff[512];
		sprintf_s(sendBuff, "server:you have connected, %s", inet_ntoa(clientAddr.sin_addr));
 		if(send(connSocket, sendBuff, strlen(sendBuff) + 1, 0) == SOCKET_ERROR)
		{
			printf("Send Error:%d\n", WSAGetLastError());
			return 0;
		}
		
		//接收客户端消息
		char recvBuff[512];
		if(recv(connSocket, recvBuff, 512, 0) == SOCKET_ERROR)
		{
			printf("Recieve Error:%d\n", WSAGetLastError());
			return 0;
		}
		printf("%s\n", recvBuff);

		cExist = getchar();						
	}

	//关闭连接、释放资源
	closesocket(svrSocket);
	closesocket(connSocket);
	WSACleanup();
}
客户端示例代码:

// sockClient.cpp : 定义控制台应用程序的入口点。
// 客户端程序

#include "stdafx.h"
#include <Winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "mswsock.lib")

int _tmain(int argc, _TCHAR* argv[])
{
	//加载释放winsock库
	WSADATA wsaData;
	if(WSAStartup(MAKEWORD(1, 1), &wsaData) != 0)
	{
		printf("%s\n", "Load WinSock Error.");
		return 0;
	}
	if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1) 
	{
		WSACleanup( );
		return 0;
	}

	//创建套接字
	SOCKET clientSocket = socket(AF_INET, SOCK_STREAM, 0);

	//与服务端连接
	SOCKADDR_IN svrAddr;
	ZeroMemory((char*)&svrAddr, sizeof(svrAddr));	
	svrAddr.sin_family = AF_INET;						//国际网区域
	svrAddr.sin_port = htons(6000);						//监听端口
	svrAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");	//服务端IP

	if(connect(clientSocket, (SOCKADDR*)&svrAddr, sizeof(SOCKADDR)) == SOCKET_ERROR)
	{
		printf("Bind Socket Error:%d\n", WSAGetLastError());
		return 0;
	}
	printf("Connect Server Succ...\n");

	//发送消息
	char sendBuff[512];
	sprintf_s(sendBuff, "client:hello,server!");
	if(send(clientSocket, sendBuff, strlen(sendBuff) + 1, 0) == SOCKET_ERROR)
	{
		printf("Send Error:%d\n", WSAGetLastError());
		return 0;
	}

	//接收服务端消息
	char recvBuff[512];
	if(recv(clientSocket, recvBuff, 512, 0) == SOCKET_ERROR)
	{
		printf("Recieve Error:%d\n", WSAGetLastError());
		return 0;
	}
	printf("%s\n", recvBuff);

	//关闭连接、释放资源
	closesocket(clientSocket);
	WSACleanup();	
	getchar();
	return 0;
}

注:当发生错误退出时,没有断开连接、释放资源。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值