目录
1.相关函数:
1.1. WSAStartup()
WSAStartup()完成Winsock的初始化
int WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
//成功返回0,失败返回非0错误代码值
MAKEWORD(1,2):主版本1,副版本2,返回0x0201
MAKEWORD(2,2):主版本2,副版本2,返回0x0202
应用:
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData)
1.2. socket()
调用socket()创建套接字
SOCKET socket(int af, int type, int protocol);
//成功返回套接字句柄,失败返回INVALID_SOCKET
参考《1.Socket_Linux(Linux下C++ socket)》
应用:
hServSocket = socket(PF_INET, SOCK_STREAM, 0);
if (hServSocket == INVALID_SOCKET) {
cout << "socket() error." << endl;
}
1.3. bind()
调用bind()函数分配IP地址和端口号
int bind(SOCKET s, const struct sockaddr * myaddr, int addrlen, sizeof(servAddr);
//成功返回0,失败返回SOCKET_ERROR
参考《1.Socket_Linux(Linux下C++ socket)》
应用:
if (bind(hServSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) {
cout << "bind() error." << endl;
}
1.4. listen()
调用listen()函数将套接字转换为可接收连接状态
int listen(SOCKET s, int n);
//成功返回0,失败返回SOCKET_ERROR
参考《1.Socket_Linux(Linux下C++ socket)》
应用:
if (listen(hServSocket, 5) == SOCKET_ERROR) {
cout << "listen() error." << endl;
}
1.5. accept()
调用accept()函数受理连接请求,如果没有连接请求的情况下调用该函数,则没有返回,直到有连接请求为止
SOCKET accept(SOCKET s, struct sockaddr* addr, int * addrlen);
//成功返回套接字句柄,失败返回INVALID_SOCKET
参考《1.Socket_Linux(Linux下C++ socket)》
应用:
szClntAddr = sizeof(clntAddr);
hClntSocket = accept(hServSocket, (SOCKADDR*)&clntAddr, &szClntAddr);
1.6. connect()
调用connect()函数向服务器发送连接请求
int connect(SOCKET s, const struct sockaddr * addr, int addrlen);
//成功返回0,失败返回SOCKET_ERROR
参考《1.Socket_Linux(Linux下C++ socket)》
应用
if (connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
cout << "connect() error." << endl;
1.7. closssocket()
调用closssocket()关闭套接字
int closesocket(SOCKET s);
//成功返回0,失败返回SOCKET_ERROR
1.8. send()/recv()
调用send()/recv()函数进行数据传输
int send(SOCKET s, const char* buf, int len, int flags);
//成功返回传输字节数,失败返回SOCKET_ERROR
- s:表示数据传输对象连接的套接字句柄
- buf:保存待传输数据的缓冲地址值
- len:要传输的字节数
- flags:传输数据时用到的多种选项信息
int recv(SOCKET s, const char * buf, int len, int flags);
//成功返回接收到的字节数(收到EOF时返回0),失败返回SOCKET_ERROR
s:表示数据接收对象连接的套接字句柄
buf:保存接受数据的缓冲地址值
len:能够接收的最大字节数
flags:接收数据时用到的多种选项信息
应用:
send(hClntSocket, message, sizeof(message), 0);
strLen = recv(hSocket, message, sizeof(message) - 1, 0);
if (strLen == -1)
cout << "recv() error." << endl;
1.9. WSACleanup()
WSACleanup()完成Winsock的注销
int WSACleanup(void);
//成功返回0,失败返回SOCKET_ERROR
2. 代码
2.1. 服务端代码
#include <iostream>
#include <WinSock2.h>
using namespace std;
int main(int argc, char** argv) {
WSADATA wsaData;
SOCKET hServSocket, hClntSocket;
SOCKADDR_IN servAddr, clntAddr;
int szClntAddr;
char message[] = "Hello, Socket's server.";
if (argc != 2) {
cout << "Usage: %s port." << argv[0] << endl;
exit(1);
}
//Step 0: WSAStartup()
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
cout << "WSAStartup() error." << endl;
}
//Step 1: socket()
hServSocket = socket(PF_INET, SOCK_STREAM, 0);
if (hServSocket == INVALID_SOCKET) {
cout << "socket() error." << endl;
}
memset(&wsaData, 0, sizeof(wsaData));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(atoi(argv[1]));
//Step 2: bind()
if (bind(hServSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) {
cout << "bind() error." << endl;
}
//Step 3: listen()
if (listen(hServSocket, 5) == SOCKET_ERROR) {
cout << "listen() error." << endl;
}
//Step 5: accept()
szClntAddr = sizeof(clntAddr);
hClntSocket = accept(hServSocket, (SOCKADDR*)&clntAddr, &szClntAddr);
if (hClntSocket == INVALID_SOCKET) {
cout << "accept() error." << endl;
}
//Step 6: send()/recv()
send(hClntSocket, message, sizeof(message), 0);
closesocket(hClntSocket);
closesocket(hServSocket);
WSACleanup();
return 0;
}
2.2. 客户端代码
int main(int argc, char** argv) {
WSADATA wsaData;
SOCKET hSocket;
SOCKADDR_IN servAddr;
char message[30];
int strLen;
if (argc != 3) {
cout << "Usage: %s <ip> <port>" << argv[0] << endl;
exit(1);
}
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
cout << "WSAStartup() error." << endl;
hSocket = socket(AF_INET, SOCK_STREAM, 0);
if (hSocket == INVALID_SOCKET)
cout << "socket() error." << endl;
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(argv[1]);
servAddr.sin_port = htons(atoi(argv[2]));
if (connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
cout << "connect() error." << endl;
strLen = recv(hSocket, message, sizeof(message) - 1, 0);
if (strLen == -1)
cout << "recv() error." << endl;
cout << message << endl;
closesocket(hSocket);
WSACleanup();
return 0;
}