windows下,socket网络编程TCP

来源:互联网 发布:阿里云服务器遭到攻击 编辑:程序博客网 时间:2024/05/15 08:54

client:

#include<stdio.h>
#include<string.h>
#include <winsock2.h>

#define port 6060

#pragma  comment(lib,"ws2_32.lib")

int main(void){
 // 初始化WSA
 // 加载socket动态链接库(dll)
    WORD sockVersion = MAKEWORD(2,2);         //请求2.2版本的WinSock库
 // 用于接收Wjndows Socket的结构信息
    WSADATA wsaData;                        
    if(WSAStartup(sockVersion, &wsaData)!=0){
        return -1;
    }
 printf("WSA初始化成功~\n");
 // 检查这个低字节是不是1,高字节是不是1以确定是否我们所请求的2.2版本
 // 否则的话,调用WSACleanup()清除信息,结束函数
 if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) {  
  WSACleanup( );
  return -1;
 }
 else{
  printf("WinSock库请求成功~\n");
 }

    // 创建一个 TCP socket
 // 创建socket操作,建立流式套接字,返回套接字号sockClient
 // SOCKET socket(int af, int type, int protocol);
 // 第一个参数,指定地址簇(TCP/IP只能是AF_INET,也可写成PF_INET)
 // 第二个,选择套接字的类型(流式套接字),第三个,特定地址家族相关协议(0为自动)
    SOCKET sClient=socket(AF_INET,SOCK_STREAM,0);//IPV4  SOCK_STREAM TCP协议

 // 处理网络通信的地址
    struct sockaddr_in addrSrv;                   
 memset(&addrSrv,0,sizeof(addrSrv));
    addrSrv.sin_family=AF_INET;
 addrSrv.sin_port=htons(port);
    //addrSrv.sin_addr.s_addr=inet_addr("127.0.0.1");//本地回路地址是127.0.0.1
 addrSrv.sin_addr.s_addr=inet_addr("192.168.253.79");

 // 将套接字sockClient与远程主机相连
 // int connect( SOCKET s, const struct sockaddr* name, int namelen);
 // 第一个参数:需要进行连接操作的套接字
 // 第二个参数:设定所需要连接的地址信息
 // 第三个参数:地址的长度
 if (connect(sClient, (sockaddr *)&addrSrv, sizeof(addrSrv)) == -1){
  printf("connect error !");
  closesocket(sClient);
  return -1;
    }
 else{
  printf("宝宝A连接成功~\n");
 }

 printf("*********************************************************\n\n");

 char rBuf[100],sBuf[100],flag=1;

 memset(sBuf,0,sizeof(sBuf));
 sprintf(sBuf, "宝宝B成功连线! \n\n");
    send(sClient,sBuf,sizeof(sBuf),0);

 memset(rBuf,0,sizeof(rBuf));
 recv(sClient,rBuf,100,0);
 printf("\t\t\t\t%s\n",rBuf);

    while(1){

  printf("宝宝B:");
  memset(sBuf,0,sizeof(sBuf));
  gets(sBuf);
        send(sClient,sBuf,sizeof(sBuf),0);
  
  if(strncmp(sBuf,"stop",4) == 0){
                printf("本宝宝结束会话,同志们再见\n");
                break;
  }

  memset(rBuf,0,sizeof(rBuf));
  recv(sClient,rBuf,100,0);
  printf("\t\t\t\t宝宝A:%s\n",rBuf);


    }
    closesocket(sClient);
    return 0;
}

 

server:

#include <stdio.h>
#include <winsock2.h>

#define port 6060

#pragma comment(lib,"ws2_32.lib")                 //加载socket动态链接库(dll)

int main(int argc, char* argv[]){
    //初始化WSA
    WORD sockVersion = MAKEWORD(2,2);            //请求2.2版本的winsock库
    WSADATA wsaData;                             //用于接收windows socket结构信息
    if(WSAStartup(sockVersion, &wsaData) != 0){  //申请WSAStartup失败则退出
        return -1;
    }
 printf("WSA初始化成功~\n");

    //创建socket操作,创建流式套接字,返回套接字号sServer(unsigned int)
 // SOCKET socket(int af, int type, int protocol); 
    //    第一个参数,指定地址簇(TCP/IP只能是AF_INET,也可写成PF_INET) 
    //    第二个,选择套接字的类型(流式套接字)
 //    第三个,特定地址家族相关协议(0为自动)
    SOCKET sServer = socket(AF_INET, SOCK_STREAM, 0);
    if(sServer == INVALID_SOCKET){
        printf("socket error !");
        return -1;
    }
 printf("创建Socket成功~\n");

 // 检查低字节、高字节是否为2以确定是否我们所请求的2.2版本 
    // 否则调用WSACleanup()清除信息,结束函数 
  if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ){ 
        WSACleanup( ); 
        return -1;  
    }
 printf("请求Winsock库成功~\n");

    //绑定IP和端口
 //套接字sServer与本地地址相连 
    //PS: struct sockaddr{ u_short sa_family; char sa_data[14];}; 
    //     sa_family指定该地址家族
 //     sa_data起到占位占用一块内存分配区的作用 
    //在TCP/IP中,可使用sockaddr_in结构替换sockaddr,以方便填写地址信息 
 
    //struct sockaddr_in{ short sin_family; unsigned short sin_port; struct in_addr sin_addr; char sin_zero[8];}; 
    //     sin_family表示地址族,对于IP地址,sin_family成员将一直是AF_INET。 
    //     sin_port指定将要分配给套接字的端口。 
    //     sin_addr给出套接字的主机IP地址。 
    //     sin_zero[8]给出填充数,让sockaddr_in与sockaddr结构的长度一样。 
    //将IP地址指定为INADDR_ANY,允许套接字向任何分配给本地机器的IP地址发送或接收数据。 
    //如果想只让套接字使用多个IP中的一个地址,可指定实际地址,用inet_addr()函数。
    sockaddr_in addrSrv;
 addrSrv.sin_family = AF_INET;
 addrSrv.sin_port = htons(port);//将INADDR_ANY转换为网络字节序,调用 htonl(long型)或htons(整型)
 //addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
 addrSrv.sin_addr.S_un.S_addr = inet_addr("192.168.253.79");

    // int bind(SOCKET s, const struct sockaddr* name, int namelen); 
    // 第一个参数,指定需要绑定的套接字; 
    // 第二个参数,指定该套接字的本地地址信息,该地址结构会随所用的网络协议的不同而不同 
    // 第三个参数,指定该网络协议地址的长度 
 //???
    if(bind(sServer, (struct sockaddr *)&addrSrv, sizeof(addrSrv)) == SOCKET_ERROR){
        printf("bind error !");         // 第二参数要强制类型转换 
    }
 printf("绑定套接成功~\n");

    //开始监听
 // 将套接字设置为监听模式(连接请求), listen()通知TCP服务器准备好接收连接 
    // int listen(SOCKET s,  int backlog); 
    // 第一个参数指定需要设置的套接字,第二个参数为(等待连接队列的最大长度)
 //???
    if(listen(sServer, 5) == SOCKET_ERROR){
        printf("listen error !");
        return -1;
    }
 printf("银河一号就绪,端口6060!\n");
  
// 客户端与用户端进行通信  

    //循环接收数据
 char rBuf[100],sBuf[100];
    SOCKET sClient;
    SOCKADDR_IN addrClient;
    int addrLen = sizeof(addrClient);
   
    while(1){
  //accept(),接收连接,等待客户端连接 
  //SOCKET accept(  SOCKET s,  struct sockaddr* addr,  int* addrlen); 
  //    第一个参数,接收一个处于监听状态下的套接字 
  //    第二个参数,sockaddr用于保存客户端地址的信息 
  //    第三个参数,用于指定这个地址的长度 
  // 返回的是向与这个监听状态下的套接字通信的套接字
        sClient = accept(sServer, (SOCKADDR *)&addrClient, &addrLen);
        if(sClient == SOCKET_ERROR){
            printf("accept error !");
            continue;
        }
  else{
   printf("***已接收连接IP:%s,等待宝宝B响应\r\n", inet_ntoa(addrClient.sin_addr));
  }

  printf("*********************************************************\n\n");

  memset(rBuf,0,sizeof(rBuf));
  recv(sClient, rBuf, 100, 0);             // 接收确认信息
  printf("\n\n\t\t\t\t%s\n",rBuf);

  memset(sBuf,0,sizeof(sBuf));
        sprintf(sBuf, "收到宝宝A消息,本机IP %s~ \n\n", inet_ntoa(addrClient.sin_addr)); 
  send(sClient, sBuf, strlen(sBuf)+1, 0);  // 发送确认信息
 
  while(1){

   // int recv(  SOCKET s,  char* buf,  int len,  int flags);  在套接字上接收数据
   //    第一个参数,建立连接后的套接字, 
   //    第二个参数,接收数据 
   //    第三个参数,接收数据的长度, 
   //    第四个参数,一些传送参数的设置 
   memset(rBuf,0,sizeof(rBuf));
   recv(sClient, rBuf, 100, 0); 
   printf("\n\t\t\t\t宝宝B:%s\n",rBuf);
   //接受到的消息为 “stop”
            if(strncmp(rBuf,"stop",4) == 0){
                printf("宝宝B已逃离地球,同志们再见\n");
                break;
            }

   //int send( SOCKET s,  const char* buf,  int len,  int flags);  在套接字上发送数据
   //    第一个参数,需要发送信息的套接字, 
   //    第二个参数,包含了需要被传送的数据, 
   //    第三个参数是buffer的数据长度, 
   //    第四个参数,一些传送参数的设置
   printf("宝宝A:");
   memset(sBuf,0,sizeof(sBuf));
   gets(sBuf);
   send(sClient, sBuf, 100, 0); 
   if(strncmp(sBuf,"stop",4) == 0){
                printf("本宝宝结束会话,同志们再见\n\n");
                break;
            }   
  }
  closesocket(sClient);
    }
    closesocket(sServer);
    WSACleanup();
    return 0;
}

 

0 0
原创粉丝点击