Winsock编程基础2(Winsock编程流程)
Posted chenxingyang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Winsock编程基础2(Winsock编程流程)相关的知识,希望对你有一定的参考价值。
1、套接字的创建和关闭
5、客户端创建套接字后的请求与服务器连接
6、收发数据
简单实例
客户端
//创建套接字 SOCKET socket( int af, //指定套接字使用的地址格式,Winsock只支持AF_INET int type, //套接字类型 int protocol//配合type使用,使用的协议 ); //---type /* * SOCKET_STREAM 流套接字,TCP * SOCKET_DGRAM 数据报套接字UDP * SOCK_RAW 原始套接字 */ //type使用上面两种时,protocol可直接赋0 //创建失败返回 INVALID_SOCKET(-1),可通过WSAGetLastError获得错误代码 //也可以使用WSASocket创建套接字,现在先不讨论 //关闭套接字 int closesocket(SOCKET s); //s为要关闭套接字句柄
2、绑定IP和端口号
int bind( SOCKE s, //套接字句柄 const struct socketaddr* name, //要关联的本地地址 int nameLen //地址长度 ); //bind作用在没有建立连接的套接字上 //绑定示例 //填充sockaddr_in结构 sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(4567); //为0时主机也会自动配置 addr.sin_addr.S_un.S_addr = INADDR_ANY; //自动使用当前主机配置 //绑定这个套接字到一个本地地址 if(bind(sListen, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)//sListen是一个套接字 { cout << "Failed bind()" << endl; return 0; }
3、设置套接字进入监听状态
4、接受连接请求
int listen( SOCKET s, //套接字句柄 int backlog //监听队列中允许保持的尚未处理的最大连接数,队满客户端会收到WSAECONNREFUSED );
SOCKET accept( //返回实际连接的套接字,与s有相同属性 SOCKET s, struct sockaddr* addr, //指向sockassr_in结构指针,用于获得对方信息 int *addrLen //指向地址长度指针 );
int connect( SOCKET s, //客户端套接字 const struct sockaddr FAR *name, //包含了要连接的服务器的地址信息 int nameLen );
int send( SOCKET s, // const char FAR *buf, //要发送的数据缓冲区地址 int Len, //缓冲区长度 int flags //调用方式,常设0 ); int recv(SOCKET s, char FAR *buf, int len, int flags)
//服务器端 #include <iostream> #include <stdio.h> #include "InitSock.h" using namespace std; int main(void) { CInitSock initSock; SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sListen == INVALID_SOCKET) { cout << "Failed socke()" << endl; return 0; } //填充sockaddr_in结构 sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(4567); addr.sin_addr.S_un.S_addr = INADDR_ANY; //绑定这个套接字到一个本地地址 if (bind(sListen, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR) { cout << "Failed bind()" << endl; return 0; } //进入监听模式 if (listen(sListen, 2) == SOCKET_ERROR) { cout << "Failed listen()" << endl; return 0; } //循环接受客户端连接请求 sockaddr_in remoteAddr; //远程客户端信息 int nAddrLen = sizeof(remoteAddr); SOCKET sClient; char szText[] = "TCP Sever Demo! "; while (true) {//接受新连接 sClient = accept(sListen, (SOCKADDR *)&remoteAddr, &nAddrLen); if (sClient == INVALID_SOCKET) { cout << "Failed accept()" << endl; continue; } cout << "接受一个连接: " << inet_ntoa(remoteAddr.sin_addr) <<endl;; //inet_ntoa()实际已过时,只能处理IPv4 //向客户端发送数据 send(sClient, szText, strlen(szText), 0); //关闭通客户端的连接 closesocket(sClient); } //关闭监听套接字 closesocket(sListen); return 0; }
#include <iostream> #include <stdio.h> #include "InitSock.h" using namespace std; int main(void) { CInitSock initSock; //创建套接字 SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (s == INVALID_SOCKET) { cout << "Failed socke()" << endl; return 0; } //也可以在这里调用binding函数绑定一个本地连接 //否则系统会自动安装 //... //填写远程地址信息 sockaddr_in servAddr; servAddr.sin_family = AF_INET; servAddr.sin_port = htons(4567); servAddr.sin_addr.S_un.S_addr = INADDR_ANY; //注意这里要填写远程服务器的TCP地址 //本地回环127.0.0.1 servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); if (connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1) { cout << "Failed connect()" << endl; return 0; } //接受数据 char buff[256]; int nRecv = recv(s, buff, 256, 0); if (nRecv > 0) { buff[nRecv] = ‘