Win Socket网络编程
原料:#include <winsock2.h>
关键API函数:
1.int WSAStartup( wVersionRequested, &wsaData );
Description: 搜索、绑定相应的Socket库
Input parameters: wVersionRequested —— WinSocket版本
wsaData —— 指向WinSocket资料的指针
Return Value: 0 if successful;
Error if failed.
2.int WSACleanup (void);
Description: 解除Socket库绑定并释放Socket库所占系统资源
3.SOCKET PASCAL FAR socket(int af,int type,int procotol);
Description: 创建套接字
Input parameters:af —— 通信发生的区域
type —— 要建立的套接字类型
procotol —— 使用的特定协议
4.int bind(SOCKET s, const struct sockaddr* name, int namelen);功能:将套接字地址与所创建的套接字号联系起来。
参数:第一个参数,指定需要绑定的套接字;
第二个参数,指定该套接字的本地地址信息
第三个参数,指定该网络协议地址的长度
5.int listen(SOCKET s, int backlog);
// 第一个参数,指定需要设置的套接字
// 第二个参数,等待连接队列的最大长度
6.SOCKET accept( SOCKET s,struct sockaddr* addr,int* addrlen);
// 第一个参数,接收一个处于监听状态下的套接字
// 第二个参数,sockaddr用于保存客户端地址的信息
// 第三个参数,用于指定这个地址的长度
// 返回监听状态下的套接字通信的套接字
7.int send( SOCKET s, const char* buf, int len, int flags);
// 第一个参数,需要发送信息的套接字
// 第二个参数,包含了需要被传送的数据
// 第三个参数,buffer的数据长度
// 第四个参数,一些传送参数的设置
8.int recv( SOCKET s, char* buf, int len, int flags);
// 第一个参数,建立连接后的套接字,
// 第二个参数,接收数据
// 第三个参数,接收数据的长度,
// 第四个参数,一些传送参数的设置
9.int connect(int sockfd,struct sockaddr * serv_addr,int addrlen);
用于客户端建立tcp连接。
//参数:sockfd:标识一个套接字。
//serv_addr:套接字s想要连接的主机地址和端口号。
//addrlen:name缓冲区的长度。
10.closesocket(SOCKET s);//关闭套接字
代码如下:
1.服务器程序
//Sever.cpp
#include <iostream>
#include <cstdio>
#include <Winsock2.h>
using namespace std;
int main()
{ // 加载socket动态链接库(dll)
WORD wVersionRequested;//使用的WinSock版本号
WSADATA wsaData; //Windows Socket资料
int err; //WSAStartup函数返回值
wVersionRequested = MAKEWORD( 2, 2 ); //使用WinSock2.2版本
err = WSAStartup( wVersionRequested, &wsaData );//绑定WinSocket动态库
if ( err != 0 )
{
cout<<"Error:socket动态链接库绑定失败!"<<endl;
return -1;
}
if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
{ // 检查低字节=2?高字节=2?确定是否为请求的2.2版本
WSACleanup( );// 否则的话,调用WSACleanup()清除信息,解除库绑定
return -1;
}
SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0); //创建套接字
SOCKADDR_IN addrSrv; //地址结构
addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));//连接套接字
listen(sockSrv, 10); //通知TCP服务器准备好接收连接
SOCKADDR_IN addrClient;//客户端地址信息
int len = sizeof(SOCKADDR);
while(true)
{ //不断等待客户端请求的到来
SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &len);
char sendBuf[100]; //发送信息字符缓冲区
sprintf(sendBuf, "服务器SEVER已连接...\n"),inet_ntoa(addrClient.sin_addr);
printf("客户端IP地址:%s\n",inet_ntoa(addrClient.sin_addr));
send(sockConn, sendBuf, strlen(sendBuf)+1, 0);//向客户端发送信息
char recvBuf[100]; //接收信息字符缓冲区
recv(sockConn, recvBuf, 100, 0);//从客户端接收信息
printf("%s\n", recvBuf); //显示客户端发送的信息
char * sockConnName = "Client";
printf("我们可以聊五句话");
int n = 5;
while(n--){
printf("还剩%d次:\n", n+1);
char recvBuf[100];
recv(sockConn, recvBuf, 100, 0);
printf("%s Says: %s\n", sockConnName, recvBuf); // 接收信息
char talk[100];
printf("Please enter what you want to say next(\"quit\"to exit):");
gets(talk);
send(sockConn, talk, strlen(talk)+1, 0); // 发送信息
printf("\n");
}
printf("\nEnd talking... \n");
closesocket(sockConn);//关闭套接字
}
printf("\n");
system("pause");
return 0;
}
2.客户端程序
// client.cpp
#include <iostream>
#include <cstdio>
#include <Winsock2.h>
using namespace std;
int main()
{ //加载socket动态链接库(dll)
WORD wVersionRequested;//使用的WinSock版本号
WSADATA wsaData; //Windows Socket资料
int err; //WSAStartup函数返回值
wVersionRequested = MAKEWORD( 2, 2 ); //使用WinSock2.2版本
err = WSAStartup( wVersionRequested, &wsaData );//绑定WinSocket动态库
if ( err != 0 )
{
cout<<"Error:socket动态链接库绑定失败!"<<endl;
return -1;
}
if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
{ // 检查低字节=2?高字节=2?确定是否为请求的2.2版本
WSACleanup( );// 否则的话,调用WSACleanup()清除信息,解除库绑定
return -1;
}
SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr = inet_addr("10.22.32.67");//本地IP地址:10.22.32.67
addrSrv.sin_family = AF_INET;
addrSrv.sin_port = htons(6000);
err=connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));//建立TCP连接
if ( err != 0 )
{
cout<<"Error:TCP连接失败!"<<endl;
return -1;
}
char recvBuf[100];
recv(sockClient, recvBuf, 100, 0);
printf("%s\n", recvBuf);
send(sockClient,"客户端Client已连接...\n", strlen("客户端Client已连接...\n")+1, 0);
printf("我们可以聊五句话");
int n = 5;
do{
printf("\n还剩%d次:", n);
char talk[100];
printf("\nPlease enter what you want to say next(\"quit\"to exit):");
gets(talk);
send(sockClient, talk, strlen(talk)+1, 0); // 发送信息
char recvBuf[100];
recv(sockClient, recvBuf, 100, 0);
printf("%s Says: %s\n", "Server", recvBuf); // 接收信息
}while(--n);
printf("End linking...\n");
closesocket(sockClient);
WSACleanup(); // 终止对套接字库的使用
printf("\n");
system("pause");
return 0;
}