C++网络编程--TCP服务器端

 

工程-》设置》连接》 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);
 } 
 
}

你可能感兴趣的:(编程,C++,网络,socket,服务器)