zoukankan      html  css  js  c++  java
  • 使用BSD socket编写Windows版的网络程序

        我们知道BSD Socket是标准的套接字规范,那么怎么在windows使用他们呢?

        我们首先要引用<winsock2.h>和ws2_32.lib

        然后,执行WSAStartup

    	#ifdef _WIN32
    	  WORD wVersionRequested;
    	  WSADATA wsaData;
    	  wVersionRequested = MAKEWORD(1, 1);
    	  iStatus = WSAStartup(wVersionRequested, &wsaData);
    	  if (iStatus != 0) {
    		return 0;
    	  }
    	  if (LOBYTE(wsaData.wVersion) != 1 ||
    		HIBYTE(wsaData.wVersion) != 1) {
    		WSACleanup();
    		return 0;
    	  }
    	#endif

        WSAStartup函数

    int WSAStartup(
      _In_   WORD wVersionRequested,
      _Out_  LPWSADATA lpWSAData
    );


        最后,执行关闭socket、清理工作

        #ifdef _WIN32
          closesocket(sockfd);
          WSACleanup();
        #endif

       WSACleanup函数

    int WSACleanup(void);


        以下程序在Win7 + VC10下编译通过
        客户端程序:

    // prjClt.cpp : Defines the entry point for the console application.
    //
    /**
     * Networking program is Win version with BSD Socket
     * Client side
     *
     * Author: xiaobin
     * Date: 2013-12-12
     */
    #include "stdafx.h"
    
    #ifdef _WIN32
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #pragma comment(lib, "ws2_32.lib")
    #else
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/in.h>
    #endif
    
    #define MAXLINE 254
    #define DEFAULT_PORT 3293
    
    int main(int argc, char* argv[])
    {
    	int 				 sockfd;
    	struct  sockaddr_in  servaddr;
    	int					 iStatus;
    	char				*sendBuff = "this is test message!";
    	
    	#ifdef _WIN32
    	  WORD wVersionRequested;
    	  WSADATA wsaData;
    	  wVersionRequested = MAKEWORD(1, 1);
    	  iStatus = WSAStartup(wVersionRequested, &wsaData);
    	  if (iStatus != 0) {
    		return 0;
    	  }
    	  if (LOBYTE(wsaData.wVersion) != 1 ||
    		HIBYTE(wsaData.wVersion) != 1) {
    		WSACleanup();
    		return 0;
    	  }
    	#endif
    
    	if (argc != 2)
    		printf("Usage: <IPaddress>>
    ");
    	
    	sockfd = socket(AF_INET, SOCK_STREAM, 0);
    	if (sockfd < 0)
    		printf("socket error
    ");
    	
    	/* check Server address */
    	// inet_pton is win version - InetPton
    	if (InetPton(AF_INET, argv[1], &servaddr.sin_addr) < 0)
    		printf("inet_pton error for %s", argv[1]);
    
    	/* Set serveraddr */
    	memset(&servaddr, 0, sizeof(servaddr));
    	servaddr.sin_family = AF_INET;
    	servaddr.sin_addr.S_un.S_addr = inet_addr(argv[1]);
    	servaddr.sin_port 	= htons(DEFAULT_PORT);
    
    	printf("%s%s%s
    ", "Connecting ", argv[1], " ...");
    
    	/* connect server */
    	iStatus = connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
    	if ( iStatus < 0 ) {
    		closesocket(sockfd);
    		printf("connect error
    ");
    	}
    
    	printf("%s
    ", "Writing...");
    	/* Write data */
    	iStatus = send(sockfd, sendBuff, (int)strlen(sendBuff), 0);
    	if (iStatus < 0) {
    		printf("%s
    ", "write data error");
    	}
    	printf("%s
    ", "Writed.");
    		
    	#ifdef _WIN32
          closesocket(sockfd);
          WSACleanup();
        #endif
    
    	return 0;
    }
    

        注意:InetPton函数只能在Windows Version >=6上实现!

        

        服务器端程序:

    // prjSrv.cpp : Defines the entry point for the console application.
    //
    /**
     * Networking program is Win version with BSD Socket
     * Server side
     *
     * Author: xiaobin
     * Date: 2012-12-18 23:35
     */
    #include "stdafx.h"
    
    #ifdef _WIN32
    #include <winsock2.h>
    #pragma comment(lib, "ws2_32.lib")
    #else
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/in.h>
    #endif
    
    #define DEFAULT_BUFLEN 128
    #define DEFAULT_PORT 3293
    
    int main(int argc, char* argv[])
    {
    	int					srvSock, client;
    	struct sockaddr_in  addrSrv;
    	int					iStatus;
    	int					len;
    	char				buff[DEFAULT_BUFLEN];
    
    	#ifdef _WIN32
    	  WORD wVersionRequested;
    	  WSADATA wsaData;
    	  wVersionRequested = MAKEWORD(1, 1);
    	  iStatus = WSAStartup(wVersionRequested, &wsaData);
    	  if (iStatus != 0) {
    		return 0;
    	  }
    	  if (LOBYTE(wsaData.wVersion) != 1 ||
    		HIBYTE(wsaData.wVersion) != 1) {
    		WSACleanup();
    		return 0;
    	  }
    	#endif
    
    	srvSock = socket(AF_INET, SOCK_STREAM, 0);
    
    	addrSrv.sin_family = AF_INET;
    	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    	addrSrv.sin_port = htons(DEFAULT_PORT);
    
    	bind(srvSock, (struct sockaddr *)&addrSrv, sizeof(addrSrv));
    	listen(srvSock, 5);
    
    	len = sizeof(struct sockaddr);
    
    	while(1) {
    		client = accept(srvSock, (struct sockaddr *)&addrSrv, (int *)&len);
    		iStatus = recv(client, buff, DEFAULT_BUFLEN, 0);
    		if (iStatus > 0)
    			printf("%s
    ", buff);
    	}
    
    
    
    
    	#ifdef _WIN32
          closesocket(client);
    	  closesocket(srvSock);
          WSACleanup();
        #endif
    
    	return 0;
    }
    


    参考文献:

    1. 《Unix 网络编程系列01》 - xiaobin

    2. 《Unix 网络编程系列05》 - xiaobin

    3. 《网络编程client和server》 - xiaobin

    4. WSAStartup - Microsoft Developer Network

    5. WSACleanup -  Microsoft Developer Network

    6. InetPton - Microsoft Developer Network


  • 相关阅读:
    技术面试之经验总结
    为何只有两篇文章?
    LOJ6364 烂柯
    mysql批量更新数据(性能优化)
    一个对象的key引发的血案
    总结与元素坐标相关的属性(再也搞不混了)
    利用nodejs搭建服务器,测试AJAX
    初探jquery之强大丰富的选择器
    Web前端开发规范手册
    IE8下标签float导致的bug。
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3473371.html
Copyright © 2011-2022 走看看