工程-》设置》连接》 ws2_32.lib 到“对象/库模块”中
#include <WINSOCK2.H> #include <STDIO.H>//使用了c的输入输出 void main() { //一, //1.要加载套接字库用WSAStartup //2.WSAStartup有两个参数:wsaData,wVersionRequested //3.wsaData:存放要加载的库版本的有关信息结构体 // wVersionRequested:版本好 int err; WORD wVersionRequested = MAKEWORD(1,1); WSADATA wsaData; err = WSAStartup(wVersionRequested,&wsaData); if (err != 0) { return; } //判断版本号是不是1.1.高字节代表Winsock副版本 //低字节代表Winsock主版本 if (LOBYTE(wsaData.wVersion != 1) || HIBYTE(wsaData.wVersion) != 1) { WSACleanup(); return; } //二 套接字 /*参数1:指定地址族,对于TCP/IP协议的套接字,它只能是AF_INET(或PF_INET) 参数2:指定Socket类型,对于1.1版本套接字只支持SOCK_STREAM流式套接字,SOCK_DGRAM数据报套接字 参数3:与特定的家族相关的协议。0,函数会自动根据地址格式和套接字类别,选择合适的协议 返回:成功返回SOCKET对象;失败返回INVALID_SOCKET,错误信息可通过WSAGetLastError函数返回*/ SOCKET sockSrv = socket(AF_INET,SOCK_STREAM,0); //三绑定 /* 函数:int bind(SOCKET,const struct sockaddr FAR *name, int namelen) 参数1:指定要绑定的套接字 参数2:指定了该套接字的本地地址信息,指向sockaddr结构的指针变量 struct sockaddr{ u_short sa_family;//指定地址家族,必须为AF_INET char sa_data[14];//内存分配区 }; 注:在TCP/IP中可用sockaddr_in结构替换sockaddr,以方便填写地址信息 struct sockaddr_in{ short sin_family;//地址族,对于IP地址,为AF_INET unsigned short sin_port;//将要分配给套接字的端口 struct in_addr sin_addr;//套接字的主机IP地址。当一台机器有多个网卡时,并让他们都接收数据时可指定为INADSDSR_ANY。 //若本机只有一个IP地址,就必须指定实际地址,可用函数inet_addr //inet_addr()函数:接受一个字符串如“192.168.0.16”,返回一个适合分配给S_addr的u_long类型的数值 //inet_ntoa()函数则相反,它接收一个in_addr结构的参数,返回一个点分十进制的IP地址字符串。 char sin_zero[8];//填充数,为使sockaddr_in和sockaddr长度一样 }; 参数3:指定上个参数的结构的长度 返回:成功0;失败返回SOCKET_ERROR,错误信息可以通过WSAGetLastError函数返回*/ SOCKADDR_IN addrSrv; //htonl()函数:转换u_long类型从主机字节序到网络字节序 //htons()函数:转换u_short类型从主机字节序到网络字节序 //网络字节序:不同的计算机存放多字节值的顺序不同,有的计算机起始地址存放低位字节,有的起始地址存放的 //高位字节。而网络传输中网络协议要求指定网络字节的顺序。 addrSrv.sin_addr.S_un.S_addr =htonl(INADDR_ANY) ; addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(6000);//端口号1024以下保留给预定义的服务。范围0~65535 bind(sockSrv,(sockaddr*)&addrSrv,sizeof(SOCKADDR)); //四监听 /*函数:int listen(SOCKET s,int backlog); 参数1:套接字描述符 参数2:等待连接队列的最大长度 */ listen(sockSrv,5); // /*函数:SOCKET accept(SOCKET s,struct sockaddr FAR *addr,int FAR *addrlen); 参数1: 参数2:【out】保存客户端的信息 参数3:【out】上一个参数长度。注:必须有初始值(结构体的大小),否则调用失败*/ /*函数:int send(SOCKET s,const char FAR *buf,int len,int flags); 参数1: 参数2: 将要传送的数据 参数3: buf长度 参数4:可选为0*/ /*函数:int recv(SOCKET s,const char FAR *buf,int len,int flags); 参数1: 参数2: 接受的数据 参数3: buf长度 参数4:可选为0*/ SOCKADDR_IN addrClient; int len = sizeof(SOCKADDR); while (1) { SOCKET sockConn = accept(sockSrv,(SOCKADDR*)&addrClient,&len); char sendBuf[100]; sprintf(sendBuf,"Welcom %s to",inet_ntoa(addrClient.sin_addr)); send(sockConn,sendBuf,strlen(sendBuf)+1,0);//加一是为了增加结束标识位 char recvBuf[100]; recv(sockConn,recvBuf,100,0); printf("%s\n",recvBuf); closesocket(sockConn); } }