win socket的server的编写流程:
1、定义win socket 结构和地址结构:SOCKET ServerSocket,ClientSocket;struct sockaddr_in SocketAddress,ClientAddr;
2、加载socket动态链接库:WSAStartup(MAKEWORD(1,1),&WsaData)
3、填写地址结构:
SocketAddress.sin_family=AF_INET;
SocketAddress.sin_port=htons (servport);
SocketAddress.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
4、将IP地址及端口和定义好的socket进行绑定:
bind(ServerSocket,(const sockaddr*)&SocketAddress,sizeof(SocketAddress))
5、将socket设置为监听状态:
listen(ServerSocket,5)
6、接受请求,发送应答:
ClientSocket = accept(ServerSocket,(struct sockaddr*)&ClientAddr,&len)
send(ClientSocket,buffer,strlen(buffer),0)
7、例子:
//server端原代码
#include <winsock.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main()
{
//定义socket;
SOCKET ServerSocket,ClientSocket;
//socket 地址结构
struct sockaddr_in SocketAddress;
struct sockaddr_in ClientAddress;
int len;
int ServerPort=5555;//定义服务器的端口
char buff[256];
for(int i=0;i<256;i++)
{
buff[i]='a';
cout<<buff[i];
}
cout<<"/nthese the world in buff"<<endl;
//以下结构保存windows的socket的详细信息
WSADATA wsd;
//servport=atoi("servport");//用户自定义的端口
//调用WSAStartup函数来加载指定版本的socket动态链接库,加载之后,socket中的一些函数
WSAStartup(MAKEWORD(1,1),&wsd);//Initialize
ServerSocket=socket(AF_INET,SOCK_STREAM,0);// Creat socket
//server address struct
memset(&SocketAddress,0,sizeof(SocketAddress));
SocketAddress.sin_family=AF_INET;//TCP/IP协议族
SocketAddress.sin_port=htons(ServerPort);//将机器子节顺序转换为TCP/IP网络子节顺序
SocketAddress.sin_addr.S_un.S_addr=htonl(INADDR_ANY);//转换IP,任何网段上的服务程序都可以与该素主机器通信
bind(ServerSocket,(const sockaddr*)&SocketAddress,sizeof(SocketAddress));//bind address
listen(ServerSocket,5);//listening
//receive looply
while(1)
{
cout<<"waiting .../n";
len=sizeof(ClientAddress);
ClientSocket=accept(ServerSocket,(struct sockaddr*)&ClientAddress,&len);
cout<<"accept client:"<<inet_ntoa(ClientAddress.sin_addr)<<" "<<ntohs(ClientAddress.sin_port)<<endl;
//send....
send(ClientSocket,buff,strlen(buff),0);
closesocket(ClientSocket);
cout<<"[server OK]"<<endl;
}
closesocket(ServerSocket);
WSACleanup();
return 0;
}
SOCKET socket(int af,int type,int protocol);
af用于指定网络类型,一般取AF_INET,表示该套接字在Internet域中进行通信,type用于指定套接字类型,若取SOCK_STREAM表示要创建的是流套接字,若取SOCK_STREAM表示创建的是数据报套接字,参数protocol用于指定网络协议,一般是0表示默认为TCP/IP协议。 成功返回指向套接字的句柄SOCKET
int bind(SOCKET s,const sockaddr* name,int namelen);
s标识一个未捆绑套接字的句柄,用来等待客户机的连接,name是赋予套接字的地址,它由struct sockaddr结构表示,该结构的格式如下:
struct sockaddr
{
u_short sa_family;
char sa_data[4];
};
该结构地址随选择的协议的不同而变换,因此一般情况下另一个与该地址结构大小相同的sockaddr_in结构更为常用,socket_in结构用来表示TCP/IP协议下的地址,在TCP/IP协议下,可以方便的通过强制类型转换把sockaddr_in结构转换为sockaddr结构。sockaddr_in结构的格式如下:
struct sockaddr_in
{
short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
sin_family字段必须设置为AF_INET,表示socket处于Internet域,sin_port字段用于指定服务器端口,sin_addr用于把一个IP地址保存为一个4字节的数。sin_zero充当填充项的职责。IP地址为INADDR_ANY时,容许服务器应用监听主机计算机上面每个网络接口上的客户机活动。
当队一个已经绑定的套接字调用bind,会返回WSAEFFAULT的错误。
int listen(SOCKET s,int backlog)
s标识一个已捆绑未连接的套接字描述符。