精华内容
下载资源
问答
  • Windows Socket

    2016-08-11 17:54:59
    Windows平台最简单的Socket通信例程源代码
  • windows socket

    2013-04-21 22:08:08
    Socket程序从windows移植到linux下需要注意的  (2010-12-21 17:39) 分类:  Socket编程 关于这个话题网上流传的是一个相同的版本,就是那个第一项是头文件的区别,但后面列出的头文件只有#include没有(估计是原版...
    源代码奉上,流程图。。。这个太简单了,你自己看看。。。。。。。
    
    //TCP
    //服务器端程序
    #include< stdio.h >
    #include< stdlib.h >
    #include< windows.h >
    #include< winsock.h >
    #include< string.h > 
    
    #pragma comment( lib, "ws2_32.lib" )
    
    #define PORT 2046
    #define BACKLOG 10
    #define TRUE 1
    
    void main( void )
    {
    int iServerSock;
    int iClientSock;
    
    char *buf = "hello, world!\n";
    
    struct sockaddr_in ServerAddr;
    struct sockaddr_in ClientAddr;
    
    int sin_size;
    
    WSADATA WSAData;
    
    if( WSAStartup( MAKEWORD( 1, 1 ), &WSAData ) )//初始化
    {
    printf( "initializationing error!\n" );
    WSACleanup( );
    exit( 0 );
    }
    
    if( ( iServerSock = socket( AF_INET, SOCK_STREAM, 0 ) ) == INVALID_SOCKET )
    {
    printf( "创建套接字失败!\n" );
    WSACleanup( );
    exit( 0 );
    }
    
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_port = htons( PORT );//监视的端口号
    ServerAddr.sin_addr.s_addr = INADDR_ANY;//本地IP
    memset( & ( ServerAddr.sin_zero ), 0, sizeof( ServerAddr.sin_zero ) );
    
    
    if( bind( iServerSock, ( struct sockaddr * )&ServerAddr, sizeof( struct sockaddr ) ) == -1 )
    {
    printf( "bind调用失败!\n" );
    WSACleanup( );
    exit( 0 );
    }
    
    if( listen( iServerSock, BACKLOG ) == -1 )
    {
    printf( "listen调用失败!\n" );
    WSACleanup( );
    exit( 0 );
    }
    
    while( TRUE )
    {
    sin_size = sizeof( struct sockaddr_in );
    iClientSock = accept( iServerSock, ( struct sockaddr * )&ClientAddr, &sin_size );
    
    if( iClientSock == -1 )
    {
    printf( "accept调用失败!\n" );
    WSACleanup( );
    exit( 0 );
    }
    
    printf( "服务器连接到%s\n", inet_ntoa( ClientAddr.sin_addr ) );
    if( send( iClientSock, buf, strlen( buf ), 0 ) == -1 )
    {
    printf( "send调用失败!" );
    closesocket( iClientSock );
    WSACleanup( );
    exit( 0 );
    }
    }
    }
    
    
    /客户端程序
    #include< stdio.h >
    #include< stdlib.h >
    #include< windows.h >
    #include< winsock.h >
    #include< string.h > 
    
    #pragma comment( lib, "ws2_32.lib" )
    
    #define PORT 2046
    #define BACKLOG 10
    #define TRUE 1
    #define MAXDATASIZE 100
    
    
    void main( void )
    {
    
    int iClientSock;
    char buf[ MAXDATASIZE ];
    struct sockaddr_in ServerAddr;
    int numbytes;
    // struct hostent *he;
    WSADATA WSAData;
    
    // int sin_size;
    
    /* if( ( he = gethostbyname( "liuys" ) ) == NULL )
    {
    printf( "gethostbyname调用失败!" );
    WSACleanup( );
    exit( 0 );
    }
    */
    
    
    if( WSAStartup( MAKEWORD( 1, 1 ), &WSAData ) )//初始化
    {
    printf( "initializationing error!\n" );
    WSACleanup( );
    exit( 0 );
    }
    
    if( ( iClientSock = socket( AF_INET, SOCK_STREAM, 0 ) ) == INVALID_SOCKET )
    {
    printf( "创建套接字失败!\n" );
    WSACleanup( );
    exit( 0 );
    }
    
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_port = htons( PORT );
    // ServerAddr.sin_addr = *( ( struct in_addr * )he->h_addr );
    ServerAddr.sin_addr.s_addr = inet_addr( "192.168.2.194" );//记得换IP
    memset( &( ServerAddr.sin_zero ), 0, sizeof( ServerAddr.sin_zero ) );
    
    if( connect( iClientSock, ( struct sockaddr * ) & ServerAddr, sizeof( struct sockaddr ) ) == -1 )
    {
    printf( "connect失败!" );
    WSACleanup( );
    exit( 0 );
    }
    
    numbytes = recv( iClientSock, buf, MAXDATASIZE, 0 );
    
    if( numbytes == -1 )
    {
    printf( "recv失败!" );
    WSACleanup( );
    exit( 0 );
    }
    
    buf[ numbytes ] = '\0';
    
    printf( "Received: %s", buf );
    
    closesocket( iClientSock );
    WSACleanup( );
    }
    
    
    /UDP
    //服务器
    #include< stdio.h >
    #include< string.h >
    #include< winsock.h >
    #include< windows.h >
    
    #pragma comment( lib, "ws2_32.lib" )
    
    #define PORT 2046
    #define BACKLOG 10
    #define TRUE 1
    #define MAXDATASIZE 1000
    
    void main( void )
    {
    int iServerSock;
    // int iClientSock;
    
    int addr_len;
    int numbytes;
    
    char buf[ MAXDATASIZE ];
    
    struct sockaddr_in ServerAddr;
    struct sockaddr_in ClientAddr;
    
    WSADATA WSAData; 
    if( WSAStartup( MAKEWORD( 1, 1 ), &WSAData ) )
    {
    printf( "initializationing error!\n" );
    WSACleanup( );
    exit( 0 );
    }
    
    iServerSock = socket( AF_INET, SOCK_DGRAM, 0 );
    if( iServerSock == INVALID_SOCKET )
    {
    printf( "创建套接字失败!\n" );
    WSACleanup( );
    exit( 0 );
    }
    
    
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_port = htons( PORT );//监视的端口号
    ServerAddr.sin_addr.s_addr = INADDR_ANY;//本地IP
    memset( & ( ServerAddr.sin_zero ), 0, sizeof( ServerAddr.sin_zero ) );
    
    
    if( bind( iServerSock, ( struct sockaddr * )&ServerAddr, sizeof( struct sockaddr ) ) == -1 )
    {
    printf( "bind调用失败!\n" );
    WSACleanup( );
    exit( 0 );
    }
    
    
    addr_len = sizeof( struct sockaddr );
    numbytes = recvfrom( iServerSock, buf, MAXDATASIZE, 0, ( struct sockaddr * ) & ClientAddr, &addr_len );
    if( numbytes == -1 )
    {
    printf( "recvfrom调用失败!\n" );
    WSACleanup( );
    exit( 0 );
    }
    
    printf( "got packet from %s\n", inet_ntoa( ClientAddr.sin_addr ) );
    printf( "packet is %d bytes long\n", numbytes );
    buf[ numbytes ] = '\0';
    printf( "packet contains \"%s\"\n", buf );
    
    closesocket( iServerSock );
    WSACleanup( );
    
    
    }
    //客户端
    #include< stdio.h >
    #include< stdlib.h >
    #include< windows.h >
    #include< winsock.h >
    #include< string.h >
    
    #pragma comment( lib, "ws2_32.lib" )
    
    #define PORT 2046
    #define MAXDATASIZE 100
    
    
    void main( void )
    {
    
    int iClientSock;
    struct sockaddr_in ServerAddr;
    
    int numbytes;
    char buf[ MAXDATASIZE ] = { 0 };
    
    WSADATA WSAData;
    if( WSAStartup( MAKEWORD( 1, 1 ), &WSAData ) )
    {
    printf( "initializationing error!\n" );
    WSACleanup( );
    exit( 0 );
    }
    
    if( ( iClientSock = socket( AF_INET, SOCK_DGRAM, 0 ) ) == -1 )
    {
    printf( "创建套接字失败!\n" );
    WSACleanup( );
    exit( 0 );
    }
    
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_port = htons( PORT );
    ServerAddr.sin_addr.s_addr = inet_addr( "192.168.2.194" );//记得换IP
    memset( &( ServerAddr.sin_zero ), 0, sizeof( ServerAddr.sin_zero ) );
    
    
    numbytes = sendto( iClientSock, buf, strlen( buf ), 0, ( struct sockaddr * ) & ServerAddr, sizeof( struct sockaddr ) );
    if( numbytes == -1 )
    {
    printf( "sendto调用失败!\n" );
    WSACleanup( );
    exit( 0 );
    }
    
    printf( "sent %d bytes to %s\n", numbytes, inet_ntoa( ServerAddr.sin_addr ) );
    
    closesocket( iClientSock );
    WSACleanup( );
    } 
    
    
    
    
    
    

    Socket程序从windows移植到linux下需要注意的

    分类: Socket编程

    关于这个话题网上流传的是一个相同的版本,就是那个第一项是头文件的区别,但后面列出的头文件只有#include没有(估计是原版的在不断转载的过程中有人不小心忘了把尖括号转义,让浏览器当html标记解析没了)的那个。现在整理了一下,以后也会不断补充内容。

    1)头文件 
    windows下winsock.h或winsock2.h
    linux下netinet/in.h(大部分都在这儿),unistd.h(close函数在这儿),sys/socket.h(在in.h里已经包含了,可以省了)

    2)初始化
    windows下需要用WSAStartup启动Ws2_32.lib,并且要用#pragma comment(lib,"Ws2_32")来告知编译器链接该lib。
    linux下不需要

    3)关闭socket
    windows下closesocket(...)
    linux下close(...)

    4)类型
    windows下SOCKET
    linux下int(我喜欢用long,这样保证是4byte,因为-1我总喜欢写成0xFFFF)

    5)获取错误码 
    windows下getlasterror()/WSAGetLastError()
    linux下,未能成功执行的socket操作会返回-1;如果包含了errno.h,就会设置errno变量

    6)设置非阻塞
    windows下ioctlsocket()
    linux下fcntl(),需要头文件fcntl.h

    7)send函数最后一个参数
    windows下一般设置为0
    linux下最好设置为MSG_NOSIGNAL,如果不设置,在发送出错后有可能会导致程序退出

    8)毫秒级时间获取
    windows下GetTickCount()
    linux下gettimeofday()

    9)多线程 
    windows下包含process.h,使用_beginthread和_endthread
    linux下包含pthread.h,使用pthread_create和pthread_exit

    10)用IP定义一个地址(sockaddr_in的结构的区别)
    windows下addr_var.sin_addr.S_un.S_addr
    linux下addr_var.sin_addr.s_addr
    而且Winsock里最后那个32bit的S_addr也有几个以联合(Union)的形式与它共享内存空间的成员变量(便于以其他方式赋值),而 Linux的Socket没有这个联合,就是一个32bit的s_addr。遇到那种得到了是4个char的IP的形式(比如127一个,0一个,0一个和1一个共四个char),WinSock可以直接用4个S_b来赋值到S_addr里,而在Linux下,可以用边向左移位(一下8bit,共四下)边相加的方法赋值。

    11)异常处理
    linux下当连接断开,还发数据的时候,不仅send()的返回值会有反映,而且还会像系统发送一个异常消息,如果不作处理,系统会出BrokePipe,程序会退出。为此,send()函数的最后一个参数可以设 MSG_NOSIGNAL,禁止send()函数向系统发送异常消息。

     

    展开全文
  • Windows Socket基础

    2020-04-09 16:17:32
    Windows Socket基础 1、调用Windows Socket的API函数获得主机的IP地址。 2、Windows Socket API中提供了一系列的GetXByY或者GetX()类型的函数,这类函数能够帮助我们以函数调用的方式获得一些常用的网络信息,为程序...

    Windows Socket基础

    1、调用Windows Socket的API函数获得主机的IP地址。
    2、Windows Socket API中提供了一系列的GetXByY或者GetX()类型的函数,这类函数能够帮助我们以函数调用的方式获得一些常用的网络信息,为程序编写提供很大的便利。
    3、所有进程在调用Windows Socket API函数之前必须对Windows Socket DLL 的使用进行初始化,以确认在该操作系统上是否支持将要进行的网络操作。
    首先,调用WSAStartup()函数,进行初始化操作;
    然后,调用Windows Socket 的GetXByY或者GetX()类函数获取主机信息;
    最后,调用WSACleanup()函数,注销程序,释放资源。

    #include "stdafx.h"
    #include <windows.h>
    #include <winsock2.h>
    #include <ws2tcpip.h>
    #include <stdlib.h>
    #include <stdio.h>
    #pragma comment (lib, "Ws2_32.lib")
    int __cdecl main(int argc, char **argv) 
    {
    	WSADATA wsaData;
    	int iResult;
    	if (argc != 2) {
            	 	printf("usage: %s server-name\n", argv[0]);
            		return 1;
       	 }
    	 iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    	if (iResult != 0) {
            		printf("WSAStartup failed with error: %d\n", iResult);
        	}
       else
    printf("WSAStartup Succeed!");
    	WSACleanup();
        	return 0;
    }
    
    

    小白起步,多谢指教~

    展开全文
  • Windows Socket 模型

    2015-10-06 13:29:07
    Windows Socket 模型 ,里面讲解写了select events 两种模型提供大家参考
  • Windows socket基础

    2017-07-13 15:01:43
    转载自:http://blog.csdn.net/ithzhang/article/details/8448655Windows socket 基础Windows socket是一套在Windows操作系统下的网络编程接口。...Windows socket是以Unix socket为基础,因此Windows socket

    转载自:http://blog.csdn.net/ithzhang/article/details/8448655


    Windows socket 基础

    Windows socket是一套在Windows操作系统下的网络编程接口。它不是一种网络协议,而是一个开放的、支持多个协议的Windows下的网络编程接口。

    Windows socket是以Unix socket为基础,因此Windows socket中的许多函数名与Unix都是一样的。除此之外它还允许开发人员充分利用Windows的消息驱动机制进行程序设计开发。

    套接字是应用层到运输层的接口。套接字用以表示一条连接的两端。每一个端点由ip和端口组成。因此套接字是由两端点的ip和端口组成。

    端口是运输层的概念,每个端口对应一个进程。因此一条连接表示一个进程与另一个进程建立联系。

    应用程序可以使用两种套接字。流套接字和数据包套接字。分别对应TCP和UDP。

    TCP提供面向连接的可靠的、无重复、有序的数据流服务。而UDP提供面向数据包的,不保证数据是可靠的、有序的和无重复的。

    在Windows环境下,使用Windows socket api进行网络程序开发时,需要调用Windows操作系统的Windows socket动态库。在应用程序中需要包含Windows sockets头文件。windows sockets 2.2版本需要包含WINSOCK2.h头文件(不区分大小写)。同时还需要添加动态库。

    一种是在头文件中添加。如:#pragma comment(lib,”WS2_32.lib”)
    另一种是在vc中添加。可以选择project ->settting,在link标签下添加wsock32.lib字符串。

    Windows sockets中定义的套接字类型SOCKET来表示套接字:

    typedef unsigned int u_int;
    typedef u_int SOCKET;
    

    其实所谓的SOCKET的类型只不过是unsigned int的别名罢了。INVALID_SOCKET表示一个无效的套接字,除此之外的0–INVALID_SOCKET-1都表示一个有效的套接字。因此在创建套接字后,都需要与INVALID_SOCKET比较,看创建的套接字是否有效。

    SOCKET s = socket(...);
    if(INVALID_SOCKET == s)
    {
      //创建失败。
    }
    

    Windows SOCKET可以支持多种不同的网络协议,并且提供与协议无关的编程接口。因此开发人员就可以相同的格式开发使用任一协议的网络应用程序,而不去关心各种协议的不同。

    每种协议都有一套不同的IP定址方案(即表示主机地址的方式)。TCP协议和UDP协议通过IP协议传输数据。

    而Windows SOCKET通过AF_INET地址家族为IP协议定址。

    #define AF_INET 2

    网络中每台主机都有一个IP地址,用32位数字来表示。TCP和UDP必须指定端口号。在Windows SOCKET中sockaddr_in 结构被用来指定IP和端口号。

    struct sockaddr_in
    {
       short sin_family;
       u_short sin_port;
       struct in_addr sin_addr;
       char sin_zero[8];
    };
    

    sin_family表示地址家族。使用TCP/IP协议的应用程序必须为aF_INET,来告诉系统使用IP地址家族 。

    sin_port指定服务的端口号。1024–49151范围内的数据被作为服务端口号,可以由用户自定义。 sin_zero字段作为填充字段。以便使得该结构与SOCKADDR结构长度相同。

    in_addr的定义如下:

    struct in_addr
    {       
        union
        {                
            struct
            {
                u_char s_b1,s_b2,s_b3,s_b4; 
            } S_un_b;  
    
            struct
            {
                u_short s_w1,s_w2; 
            } S_un_w;
    
            u_long S_addr;
    
        } S_un;
    }
    

    很显然它是一个存储ip地址的联合体,有三种表达方式:

    第一种用四个字节来表示IP地址的四个数字;
    第二种用两个双字节来表示IP地址;
    第三种用一个长整型来表示IP地址。

    给in_addr赋值的一种最简单方法是使用inet_addr函数,它可以把一个代表IP地址的字符串赋值转换为in_addr类型,如addrto.sin_addr.s_addr=inet_addr(“192.168.0.2”);

    其反函数是inet_ntoa,可以把一个in_addr类型转换为一个字符串。

    sockaddr类型sockaddr类型是用来表示socket地址的类型,同上面的sockaddr_in类型相比,sockaddr的适用范围更广,因为sockaddr_in只适用于TCP/IP地址。

    sockaddr的定义如下:

    struct sockaddr
    { 
        u_short sa_family;
        char  sa_data[14];
    };
    

    可知sockaddr有16个字节,而sockaddr_in也有16个字节,所以sockaddr_in是可以强制类型转换为sockaddr的。事实上也往往使用这种方法。

    不同cpu处理多字节时处理方式不同。Intel x86cpu对多字节的处理方式为高对高低对低。但是在网络上采用的是高对低,低对高的方式。因此也就存在所谓主机字节序和网络字节序的处理问题。

    Htonl和htons函数实现主机字节顺序和网络字节序的转换功能。H代表host,主机。N代表net。L代表long。S代表short。不要使用htonl转换short哦,楼主就有一次犯了这个错误,找了好久才找到原因。

    当然也有从网络字节序到主机字节序的转换函数:ntohl和ntohs。

    除了支持TCP/IP协议之外,Windows SOCKET还支持IPX/SPX、ATM和红外线通信协议等等,它们都有自己的定址方法,感兴趣的同学可以参考其他资料。


    基本的套接字编程

    在使用套接字进行编程之前,无论是服务器还是客户端都必须加载Windows SOCKET动态库。函数WSAStartup就实现了此功能。它是套接字应用程序必须调用的第一个函数。

    int WSAStartup(WORD wVersionRequested, LPWSADATA lpwsadata);
    

    第一个参数指定准备加载的Windows SOCKET动态库的版本。一般使用宏MAKEWORD构造。如MAKEWORD(2,2)表示加载2.2版本。

    WSADATA会返回被加载动态链接库的基本信息。如是否加载成功,以及当前实际使用的版本。具体结构不再介绍。

    初始化socket之后,需要创建套接字。socket函数和WSASocket函数可以实现此功能。

    SOCKET socket(int af, int type, int protocol);
    

    af 表示使用协议的地址家族。创建TCP或UDP的套接字是使用AF_INET。

    type 表示套接字的类型。有SOCK_STREAM、SOCK_DGRAM和SOCK_RAM三种类型。分别表示流、数据包、原始套接字。

    protocol 指示使用的协议。对于SOCK_STREAM套接字类型,该字段可以为IPPROTO_TCP或0。对于SOCK_DGRAM套接字类型,该字段为IPPROTO_UDP或0。

    当函数创建成功时,返回一个新建的套接字句柄。否则将返回INVALID_SOCKET。如:

    SOCKET s = socket(AF_INET,SOCK_STREAM, 0);
    if(s == INVALID_SOCKET)
    {
       //失败。
    }
    

    bind函数

    在创建套接字之后就需要调用bind函数将其绑定到一个已知的地址上。

    int bind(SOCKET s, const struct sockaddr*name, int namlen);
    

    s为要绑定的套接字,name为要绑定的地址。namelen为sockaddr长度。

    函数调用成功将返回0,否则返回值为SOCKET_ERROR。如果程序不关心分配给它的地址,可使用INADDR_ANY或将端口号设为0。端口号为0时,Windows SOCKET将给应用程序分配一个值在1024-5000之间唯一的端口号。

    示例:

    struct sockaddr_in addr;
    
    int nServerPort=5500;
    int nErrorCode;
    
    addr.family=AF_INET;
    addr.port=htons(nServerPort);
    addr.sin_addr.S_addr=htonl(INADDR_ANY);
    
    SOCKET s=socket(AF_INET,SOCK_STREAM,0);
    if(s==INVALID_SOCKET)
    {
      //失败。
    }
    
    nErrorCode=bind(s,(SOCKADDR*)&addr,sizeof(addr));
    if(nErrorCode==SOCKET_ERROR)
    {
      //失败。
    }
    

    listen函数将套接字设定为监听模式。

    int listen ( SOCKET s, int backlog);
    

    s为要设置监听模式的套接字。

    backlog指定等待连接的最大队列长度。当函数成功时返回0,否则返回SOCKET_ERROR。假如backlog为3,则说明最大等待连接的最大值为3.如果有四个客户端同时向服务器发起请求,那么第四个连接将会发生WSAEWOULDBLOCK错误。当服务器接受了一个请求,就将该请求从请求队列中删去。

    int ret=listen(s, 3);
    if(ret == SOCKET_ERROR)
    {
       //失败。
    }
    

    accept函数接受客户端的一个连接请求。

    SOCKET accept{SOCKET s, struct sockaddr* addr, int* addrlen);
    

    s为监听套接字。

    addr返回客户端地址。

    addrlen返回addr的长度。

    函数执行成功时:
    1:主机接受了等待队列的第一个请求。
    2:addr结构返回客户端地址。
    3:返回一个新的套接字句柄。服务器可以使用该套接字与客户端进行通信。而监听套接字仍用于接受客户端连接。

    SOCKET sListen;     //监听套接字。
    SOCKET sAccept;     //接受套接字。
    
    sockaddr_in addrClient;     //客户端地址。
    int addrClientLen=sizeof(addrClient);
    
    sAccept = accept(sListen,(SOCKADDR*)&addrClient,&addrClientLent);
    if(INVALID_SOCKET == sAccept)
    {
       //失败。
    }
    

    recv()函数

    recv()和WSARecv()函数用于接收数据。

    int recv(SOCKET s, char *buf, int len, int flags);
    

    s 为接收数据套接字。
    buff 接受缓冲区。
    len 缓冲区长度。
    flags 该参数影响函数的行为。它可以是0,MEG_PEEK和MSG_OOB。0表示无特殊行为。MSG_PEEK会使有用的数据被复制到buff中,但没有从系统缓冲区内将这些数据删除。MSG_OOB表示处理外带数据。

    recv函数返回接收的字节数。当函数执行失败时返回SOCKET_ERROR。

    SOCKET s;
    char buff[128];
    
    nReadlen = recv(s,buff,128,0);
    if(SOCKET_ERROR == nReadlen)
    {
        // 失败
    }
    

    send函数

    send()和WSASend()用于发送数据。

    int send(SOCKET s, const char* buff, int len, int flags);
    

    s 为发送套接字。
    buff 为发送缓冲区。
    len 发送数据长度。
    flags 可以是0或MSG_DONTROUTE或MSG_OOB。0表示无特殊行为。MSG_DONTROUTEyaoqiu传输层不要将此数据路由出去。MSG_OOB表示该数据应该被外带发送。

    函数成功时返回实际发送的字节数。失败返回SOCKET_ERROR。

    SOCKET s;
    char buff[128];
    int ret;
    strcpy(buff, ”sendData”);
    
    ret=send(s,strlen(buff),0);
    if(SOCKET_ERROR==ret)
    {
        // 失败
    }
    

    closesocket()函数

    closesocket()函数用以关闭套接字。释放套接字所占资源。

    int closesocket(SOCKET s);
    

    调用过closesocket函数的套接字继续使用时会返回WSAENOTSOCK错误。

    shutdown()函数。

    Shutdown()函数用于通知对方不再发送数据或者不再接收数据或者既不发送也不接收数据。

    int shutdown(SOCKET s, int how);
    

    how参数可以是:
    SD_RECEIVE 表示不再接收数据,不允许再调用接收数据函数。
    SD_SEND 表示不再发送数据。
    SD_BOTH 表示既不发送也不接收数据。

    connect函数实现连接服务器的功能。

    int connect(SOCKET s, const struct sockaddr*name, int namelen);
    

    s 为套接字。
    name 为服务器地址。
    namelen 为sockaddr结构长度。

    函数执行成功返回0,否则返回SOCKET_ERROR。

    SOCKET s;
    ULONG ulServIp;
    USHORT ServPort;
    int ret;
    
    SOCKADDR_IN servAddr;
    servAddr.sin_family = AF_INET;
    servAddr.sin_addr.S_addr = htonl(ulServIp);
    servAddr.sin_port = htons(ServPort);
    
    int len = sizeof(servaddr);
    ret = connect(s,(SOCKADDR*)&servAddr,sizeof(servAddr));
    if(ret == SOCKET_ERROR)
    {
        // 失败
    }
    

    创建套接字后,可以对它的各种属性进行设置。可以调用getsockopt()函数来返回套接字选项信息。setsockopt()设置套接字选项。

    getsockopt()函数

    它用于获取套接字选项信息:

    int getsockopt(SOCKET s, int level, int optname, char *optval, int optlen);
    

    s为要取得选项的套接字。
    level为选项级别,有SOL_SOCKET和IPPROTO_TCP两个级别。
    optname套接字选项名称。
    optval该参数返回套接字选项名称对应的值。
    optlen为缓冲区optval大小。

    函数成功,返回值为0。否则返回SOCKET_ERROR。

    int Bufflen;
    int noptlen=sizeof(nBufflen);
    
    int ret=getsockopt(s,SOL_SOCKET,SO_RCVBUF,(char*)&BuffLen,&noptlen);
    if(ret==SOCKET_ERROR)
    {
        // 失败
    }
    

    setsockopt函数。

    它可以设置套接字选项。若不能正确设置socket属性,则数据的发送和接收会失败。

    int setsockopt(SOCKET s, int level, int optname, char *optval, int optlen);
    

    s 为要取得选项的套接字。
    level 为选项级别,有SOL_SOCKET和IPPROTO_TCP两个级别。
    optname 套接字选项名称。
    optval 参数设置套接字选项的值。
    optlen 为optval大小。

    下列代码首先调用getsockopt函数获得默认接收缓冲区的大小,然后调用setsockopt将接收缓冲区大小设置为原来的10倍。再次调用getsockopt来检查是否设置成功:

    int opt;
    int noptlen=sizeof(opt);
    
    int ret = getsockopt(s,SOL_SOCKET,SO_RECVBUFF,(char*)&opt,noptlen);
    if(ret == SOCKET_ERROR)
    {
        // 失败
    }
    
    opt *= 10;
    ret = setsockopt(s,SOL_SOCKET,SO_RECVBUFF,(char*)&opt,noptlen);
    if(ret == SOCKET_ERROR)
    {
        // 失败
    }
    
    int newopt;
    getsockopt(s,SOL_SOCKET,SO_RECVBUFF,(char*)&newopt,&noptlen);
    if(newopt != opt)
    {
      //设置失败。
    }
    

    当设置SOL_SOCKET选项级别时,调用setsockopt函数和getsockopt函数所设置或获取的信息为套接字本身的特征,这些信息与基层协议无关。

    SOL_SOCKET级别包括以下类型:

    SO_ACCEPTCONN      bool类型。如果为真,表明套接字处于监听模式。
    SO_BROADCAST       bool类型,如果为真,表明套接字已设置成广播消息发送。
    SO_DEBUG           bool类型。如果为真,则允许输出调试信息。
    SO_DONTLINGER      bool类型。如果为真,则禁止SO_LINGER。
    SO_DONTROUTE       bool类型。如果为真,则不会做出路由选择。
    SO_ERROR           int 类型。返回和重设以具体套接字为基础的错误代码。
    SO_KEEKPALIVE      bool类型。如果为真,则套接字在会话过程中会发送保持活动消息。
    SO_LINGER          struct linger*类型,设置或获取当前的拖延值。
    SO_OOBINLINE       bool如果为真,则带外数据会在普通数据流中返回。
    SO_RECVBUF         int类型。设置或获取接收缓冲区长度。
    SO_REUSEADDR       bool类型。如果为真,套接字可以与一个正在被其他套接字使用的地址绑定。
    SO_SNDBUF          bool类型。设置或获取发送缓冲区大小。
    SO_TYPE            int类型。返回套接字类型,如SOCK_DGREAM,SOCK_STREAM。
    SO_SNDTIMEO        int类型。设置或获取套接字在发送数据的超时时间。
    SO_RECVTIMEO       int类型,设置或获取套接字在接收数据的超时时间。

    WSAGetLastError函数

    该函数用来在Socket相关API失败后读取错误码,根据这些错误码可以对照查出错误原因。

    GetComputerName()用来获取计算机名称:

    // lpBuffer是用来存储返回的名称的缓冲区。
    BOOL GetComputerName( LPTSTR lpBuffer, LPDWORD lpnSize);
    

    lpBuffer 为缓冲区。
    lpnSize 为缓冲区大小。同时它也返回计算机名称的长度。
    此函数不属于winsock库函数。使用之前不需要初始化库。

    使用方法为:

    TCHAR szHostName[20];
    DWORD dwSize = 20;
    GetComputerName(szHostName, &dwSize);

    gethostname()函数:

    此函数为WinSock库函数,使用之前需要初始化WinSock库。

    int  gethostname(char* name, int namelen);
    

    name 为存储主机名缓冲区。
    namelen 为缓冲区长度。


    以上参考自《Windows sockets网络开发–基于Visual C++实现》如有纰漏,请不吝赐教!!!
    2012.12.28于山西大同

    展开全文
  • windows socket源码

    2007-09-21 15:58:12
    windows socket源码
  • Windows Socket编程

    2013-12-29 00:29:44
    Windows Socket编程 WindowsSocket编程主要包括以下几部分: 服务端  1、初始化Windows Socket库。  2、创建Socket。  3、绑定Socket。  4、监听。  5、Accept。  6、接收、发送数据。 客户端 ...
    展开全文
  • Windows Socket实例

    2014-05-07 23:29:46
    WindowsSocket编程主要包括以下几部分: 服务端  1、初始化Windows Socket库。  2、创建Socket。  3、绑定Socket。  4、监听。  5、Accept。  6、接收、发送数据。 客户端  1、初始化Windows ...
  • Windows Socket API函数

    2015-09-19 11:51:05
    Windows Socket API函数 socketwindows数据结构struct服务器网络 Windows Socket API函数 一、WSAStartup函数 int WSAStartup( WORD wVersionRequested, LPWSADATA lpWSAData ); 使用...
  • 4 --- Windows Socket和Linux Socket编程有什么区别 4 --- Windows Socket和Linux Socket编程有什么区别 - lcryby - 博客园4 --- Windows Socket和Linux Socket编程有什...
  • windows socket错误码及出错原因,可以参考一下。也可MSDN。
  • Windows Socket 异步发送接收消息 连接
  • Windows Socket和Linux Socket编程的区别

    千次阅读 2017-08-14 16:03:27
    来源:Windows Socket和Linux Socket编程的区别 SOCKET在原理上应该是一样的,只是不同系统的运行机置有些不同。 Socket 编程 windows到Linux代码移植遇到的问题 1、一些常用函数的移植  ...
  • windows socket函数详解

    2017-11-12 20:18:51
    本文章主要包括了C++语言框架下对windows socket 的总结。
  • WindowsSocket五种模型

    2012-11-21 18:27:09
    有关5中windows Socket模型的详细讲解
  • 精通windows socket网络编程VC++光盘代码内容
  • 这是我做WINDOWS SOCKET开发的积累,其中结合了很多WINDOWS SOCKET实际使用到的技术,是学习WIN SOCK开发的宝典。
  • windows socket TCP server client sample code
  • windows socket IOCP讲解和代码 打包了pdf和代码和visual studio 工程

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,470
精华内容 6,988
关键字:

windowssocket