美文网首页
SOCKET建立步骤

SOCKET建立步骤

作者: dovlie | 来源:发表于2017-07-27 00:00 被阅读547次

    C语言   粗体字公共部分  斜体字为服务器 其余为客户端

    服务器客户端

    #include

    #include

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

    int main(int argc, char* argv[])

    {

    WSADATA wsaData;

    WORD sockVersion = MAKEWORD(2,0);//指定版本号,使用WINSOCK2版本

    ::WSAStartup(sockVersion, &wsaData);//载入winsock的dll启动函数

    第一个参数是WINSOCK版本号,第二个参数是指向WSADATA的指针

    SOCKET s = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    //创建套接字基于TCP,第一个是协议域,AF_IMET决定了要用IPV4地址(32位)与端口号(16位)的组合,把ipv4地址和端口号组合赋给socket;第二个指定socket的类型;第三个指定协议,此处对应TCP传输协议,简单来说既是(使用TCP/IP协议;传输过程使用TCP;不适用其他特殊协议)

    if(s == INVALID_SOCKET)

    {

    printf("error");

    ::WSACleanup();

    //终止函数,清理,释放资源应用程序在完成对请求的socket库的使用后WSAClanup,

    清除套接字资

    函数来接触与socket库的绑定并且释放socket库所占用的系统资源

    return 0;

    }

    sockaddr_in sin;//socket中装入地址信息

    sockaddr_in servAddr;//定义套接字地址

    sin.sin_family = AF_INET;//sin.family表示地址族,对于IP地址,sin_family将一直是AF_INET

    servAddr.sin_family = AF_INET;//储存IP地址,INADDR_ANY就是制定地址为0.0.0.0的地址,

    这个地址事实上表示不确定地址,或“所有地址”、“任意地址”

    sin.sin_port = htons(8888);//端口号表示服务器监听的端口号使8888

    servAddr.sin_port = htons(8888);//端口号表示客户端接受服务器8888端口号

    sin.sin_addr.S_un.S_addr = INADDR_ANY;//储存地址,INADDR就是指定地址为

    0.0.0.0的地址,这个地址事实上表示不确定地址,也就是所有的地址或任意地址

    servAddr.sin_addr.S_un.S_addr = inet_addr("192.168.31.220");//本地IP地址,

    inet_addr()将IP地址转为点分十进制的格式

    //绑定socket,绑定地址及端口号

    if(::bind(s, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)

    参数一:指定与那个套接字绑定

    参数二:指定地址

    参数三:确定恢复多少数据

    {

    printf("error");

    ::WSACleanup();//清理释放资源

    return 0;

    }

    //bind函数把一个地址族中的特定地址赋给socket。第一个参数是socket描述字,通过socket创建,唯一标识一个socket。bind()函数就是将这个表述字绑定一个名字。第二个参数指向要绑定给socket的协议地址。第三个参数对应的是地址的长度。

    为服务器端定义的这个监听的socket指定一个地址及端口(port),这样客户端才知道待会儿要

    连接哪一个地址的哪个端口,为此我们要调用bind函数

    //监听socket,监听客户端的连接请求

    if(::listen(s, 2) == SOCKET_ERROR)//监听客户端请求

    参数一:被listen函数调用的套接字

    参数二:连接数量的上限

    {

    printf("error");

    ::WSACleanup();//释放资源

    return 0;

    }

    //连接主动完成连接过程,三次握手协议,谁调用了connet函数谁就是先发送数据的一方

    if(::connect(s, (sockaddr*)&servAddr, sizeof(servAddr)) == -1)//连接服务器

    参数一:指定数据发送的套接字

    参数二:指定数据发送的目的地址,也就是服务端地址

    {

    printf("error");

    ::WSACleanup(); //释放资源

    return 0;

    }

    char buff[156];//缓冲区

    int nRecv = ::recv(s, buff, 156, 0);//接收数据并打印到屏幕上

    //不论是客户还是服务器应用程序都用recv函数从TCP连接的另一端接收数据。

    第一个参数:指定接收端套接字描述符

    第二个参数:指明一个缓冲区,该缓冲区用来存放recv函数接收到的数据

    第三个参数:指明buf的长度

    第四个参数:一般设置0

    if(nRecv > 0)

    {

    buff[nRecv] = '\0';

    printf("接受数据:%s",buff);

    }

    sockaddr_in remoteAddr;

    int nAddrLen = sizeof(remoteAddr);

    SOCKET client;

    char szText[] = "peter\n";//缓冲区数据

    while(1)循环接受连接请求

    {accept默认会阻塞进程,直到有一个客户建立连接后返回,他返回的是一个新

    可用的套接字,这个套接字是连接套接字

    /*accept服务器端使用,调用函数进入阻塞状态,等待用户连接,如果没有客户端进行连接,程序就在这个地方。

    不会看到后面。如果有客户端连接,那么程序就执行一次然后继续循环到这里等待。*/

    client = ::accept(s, (SOCKADDR*)&remoteAddr, &nAddrLen);

    参数一:监听套接字,这个套接字用来监听一个端口,当有一个客户与服务器连接时,它使用这个端口号,而此时这个端口号正与这个套接字关联。当然客户不知道套接字这些细节,他只知道一个地址和一个端口号

    参数二:这是一个结果参数,它用来接受一个返回值,这返回值指定客户端的地址。

    //acc

    if(client == INVALID_SOCKET)

    {

    printf("error");

    continue;

    }

    printf("接受到一个连接:%s\r\n",inet_ntoa(remoteAddr.sin_addr));客户端IP

    ::send(client, szText, strlen(szText), 0); //发送数据,发送本地时间给客户端

    //不论是客户还是服务器应用程序都用send函数来想TCP连接的另一端发送数据,

    客户程序一般都用send函数向服务器发送请求,而服务器则通常用send函数

    来向客户程序发送应答。

    第一个参数:指定发送端套接字描述符

    第二个参数指明一个存放应用程序要发送数据的缓冲区

    第三个参数指明实际要发送的数据的字节数

    第四个参数一般设置0

    ::closesocket(client);//关闭套接字,关闭连接

    }

    ::closesocket(s);关闭套接字

    ::WSACleanup();

    return 0;

    }


    2015.7.7

    相关文章

      网友评论

          本文标题:SOCKET建立步骤

          本文链接:https://www.haomeiwen.com/subject/apsakxtx.html