「TCP」--WinSocket笔记

本文很多内容 转载自WinSocket

 

C/S 通信过程

头文件

WinSock.h

WinSock2.h 兼容第一版本的WinSock.h,并且支持异步。

参数说明

1.AF等实参

  • AF_INET(又称 PF_INET)是 IPv4 网络协议的套接字类型;
  • AF_INET6 则是 IPv6 的;
  •  AF_UNIX 则是 Unix 系统本地通信。

选择 AF_INET 的目的就是使用 IPv4 进行通信。因为 IPv4 使用 32 位地址,相比 IPv6 的 128 位来说,计算更快,便于用于局域网通信

2. sockaddr

详细出处 百度百科


struct sockaddr_in { // winsock2.h 定义
        short   sin_family; 
        u_short sin_port; 
        struct  in_addr sin_addr; 
        char    sin_zero[8]; 
};

typedef struct in_addr
{
    union{
            struct { unsigned char s_b1,s_b2,s_b3,s_b4; } S_un_b;
            struct { unsigned short s_w1,s_w2; } S_un_w;
            unsigned long S_addr; //s_addr按照网络字节顺序存储IP地址
    }S_un;
}in_addr;

sin_family :指代协议族,在socket编程中只能是AF_INET

sin_port :存储端口号(使用网络字节顺序),在linux下,端口号的范围 :0~65535,同时0~1024范围的端口号已经被系统使用或保留。

sin_addr :存储IP地址,使用in_addr这个数据结构 ????(没懂!,搜了半天)

sin_zero :是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节。

函数解释

1.WASStartup

初始化套接字环境,本函数必须是应用程序或DLL调用的第一个Windows Sockets函数.它允许应用程序或DLL指明Windows Sockets API的版本号及获得特定Windows Sockets实现的细节.应用程序或DLL只能在一次成功的WSAStartup()调用之后才能调用进一步的Windows Sockets API函数.

//begin 初始化网络环境
int m_WSAerr = WSAStartup(MAKEWORD(2, 2), &wsaData);
if(NO_ERROR!=m_iWSAerr)
{
    printf("WSAStartup failed with error: %d\n", m_iWSAerr);
    return -1;
}//end

2.Clearup:

清理套接字环境,和上面的WSAStartup相反,该函数是在程序不在对任何Windows Sockets函数调用后,用其来清理套接字环境的
 

int  WSACleanup (void);

3、SOCKET socket(int af, int type, int protocol);

建立套接字

参数af用于指定网络地址类型,一般取AF_INET,表示该套接字在Internet域中,进行通信。

参数type用于知道套接字的类型,若取SOCK_STREAM表示创建的套接字是流套接字,而取SOCK_DGRAM创建数字报套接字。

参数protocol用于指定网络协议,一般取0,表示默认为TCP/IP协议。 若套接字创建成功则该函数返回创建的套接字句柄SOCKET,否则产生INVALID_SOCKET错误。

//begin socket 一个套接字
hTcpSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == hTcpSocket)
{
MJS_LOG_ERROR("socket failed with error: \n");
WSACleanup();
return -1 ;
}//end

4 int listen(SOCKE s, int backlog)

将套接字置入监听模式并准备接受连接请求。

参数s是服务器端套接字;

参数backlog是accept阻塞队列的长度。

如无错误发生,listen函数返回0,失败则返回SOCKET_ERROR错误,应用程序可通过WSAGetLastError()获取相应错误代码

5、SOCKET accept( SOCKET s, struct sockaddr* addr, int* addrlen )

 

参数s同上;

addr是一个有效的SOCKADDR_IN结构的地址;

addrlen是sockaddr_in结果的长度。

accept函数返回后,addr参数变量中会包含发出连接请求的那个客户机的IP地址信息,而addrlen参数则指出该结构的长度,并返回一个新的套接字描述符,它对应于已经接受的那个客户机连接。

6.int bind( SOCKET s, const struct sockaddr* name, int namlen )

绑定到本地,name中指定的IP应该是当前运行该程序机器的IP。

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

连接到服务器

8. int send( SOCKET s, const char* buf, int len, int flags )

失败时返回 -1/SOCKET_ERROR

       sockfd:已建立连接的发送端套接字描述符(非监听描述符)

       buf:应用要发送数据的缓存

       len:实际要发送的数据长度

       flags:一般设置为0。  flags可取的值有:0、MSG_DONTROUTE或MSG_OOB或这些标志的按位或运算。

9、int recv( SOCKET s, char* buf, int len, int flags );

 表示从接收缓冲区拷贝数据

s是准备接收数据的套接字

buf是即将收到数据的字符缓冲区

len则是准备接受的字节数或buf缓冲的长度

flags一般指定为0.参数可以是0、MSG_PEEK或MSG_OOB或这些标志的按位“或”运算。

成功时,返回拷贝的字节数,失败返回-1。阻塞模式下,recv/recvfrom将会阻塞到缓冲区里至少有一个字节(TCP)/至少有一个完整的UDP数据报才返回,没有数据时处于休眠状态。若非阻塞,则立即返回,有数据则返回拷贝的数据大小,否则返回错误-1,置错误码为EWOULDBLOCK。

10、int shutdown( SOCKET s, int how );

其中,how参数用于描述禁止哪些操作,它可取的值有:SD_RECEIVE、SD_SEND或SD_BOTH。 如果是SD_RECEIVE,就表示不允许再调用接收函数, 如果选择SD_SEND,表示不允许再调用发送函数, 如果是SD_BOTH, 则表示取消连接两端的收发操作。 如果没有错误发生,shutdown()返回0,否则返回SOCKET_ERROR错误。

11、 int closesocket(SOCKET s );

s是要关闭的套接字描述字,再利用套接字执行调用就会失败。

12 int gethostname(char *name, size_t len):

这个函数,调用后,会将主机名保存在name里面。而len是name的大小。该函数返回0表示成功,否则失败。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值