tcp/ip网络编程一般模型

 网络编程有固定的模型和一定数量的函数,其实只要将模型整理出来,就可以做到编程游刃有余。以下是笔者自己整理的模型,希望能够起到抛砖引玉的作用。

客户端模型
1 用socket创建套接字
2 用connect来连接服务器
3 用send和recv发送和接受数据
1 socket函数参数
SOCKET sClient;
 sClient=socket(int af, int type, int protocol );第一个参数是地址族,对于TCP/IP型 只能是AF_INET;第二个参数是socket类型 SOCK_STREAM产生流式套接字 SOCK_DGRAM是产生数据报套接字,TCP/IP协议使用SCOK_STREAM。第三个参数,特定IPPROTO_TCP或者0。socket创建成功则返回一个SOCKET数据类型,若失败 则返回是INVALID_SOCKET。出现失败时,在一个多线程的环境下,WSACleanup()中止了Windows Sockets在所有线程上的操作。
2 在上述建立套接字后,需要构建服务器信息 用到sockaddr_in这个结构体  
例如  sockaddr_in clientService(服务器地址结构体); 之后是sockaddr_in结构体的参数
sin_family指代协议族,在socket编程中只能是AF_INET,sin_port存储端口号(使用网络字节顺序)htons是将主机字节格式转换成网络字节格式sin_addr存储IP地址 s_addr按照网络字节顺序存储IP地址。inet_addr()如果正确执行将返回一个无符号的长整数型,如果传入的字符串不是一个合法的IP地址 将返回INADDR_NONE。
3 connect(参数1,参数2,参数3)作用是将socket套接字连接到sockaddr指定的服务器上,参数1是之前创建的套接字 即为 sClient。参数2是sockaddr型服务器,参数3是sockaddr结构长度。发生错误时 返回SOCKET_ERROR,然后需要函数closesocket(sClient),WSACleanup结束线程操作。
4send(参数1,参数2,参数3,参数4)
参数1是之前创建的套接字 参数2是指向包含要发送的数据的缓冲区的指针 参数3是所指向的缓冲区的长度。准确的说,应该是所要发送的数据的长度,因为不是缓冲区的所有数据都要同时发送。第四个参数是0.
第2个参数相关举例
①char *sendbuf = "Client: sending data test";
iResult = send( ConnectSocket, sendbuf, (int)strlen(sendbuf), 0 )
②char sendMessage[]="ZhongXingPengYue"; 
ret = send (sClient, (char *)&sendMessage, sizeof(sendMessage), 0)
③int rnt=send(ConnectSocket,"GET\r\n\r\n",strlen("GET\r\n\r\n"),0);
返回值 出现错误是返回值为 SOCKET_ERROR 依然是closesocket(sClient)
WSACleanup();
④recv(参数1,参数2,参数3,参数4)
char recvBuf[100]; 
recv(sClient,recvBuf,100,0);
recv函数返回其实际copy的字节数 recv 1是成功 0是对端关闭 -1
服务器端
①不管是服务器还是客户端  都需要初始化winsock库 也就是
  WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != NO_ERROR) {
        wprintf(L"WSAStartup function failed with error: %d\n", iResult);
        return 1;
    }(虽然不太懂什么意思 但是套路 就记住吧)
②创建监听套接字 依然用socket
   slisten=socket(参数1,参数2,参数3)
③绑定 用到bind 将创建好的套接字绑定到某个地址和端口上
   bind(socks,const struct sockaddr FAR*name,int namelen)
第一个参数是创建的套接字。
第二个参数,指定该套接字的地址信息,这里即服务器的地址信息,它仍是指向struct sockaddr_in类型的结构体的指针。这个结构体和客户端调用connect函数之前构建服务器地址信息的一样。
第三个参数是地址的信息的长度。
④监听连接,使用listen函数。是将制定的套接字设置为监听模式,如ret=listen(slisten,5)
第一个参数是要设置为监听的套接字描述符
第二个参数是等待连接队列的最大的长度。
⑤接受客户端的连接请求。使用accept函数来接受客户端发送的连接请求。
SOCKET AcceptSocket;
sockaddr_in clientaddr;
AcceptSocket=accept(ListenSocket, (sockaddr *)&clientaddr, &clientaddr_Bytes)
accept第一个参数是之前设定的套接字。
      第二个参数是个返回值,它指向一个struct sockaddr类型的结构体的变量,保存了发起连接的客户端得IP地址信息和端口信息。
      第三个参数是一个返回值,指向整型的变量,保存了返回地址信息的长度 此处用length = sizeof(saClient)
⑥是发送和接受此处与之前的客户端一样
char sendMessage[]="hello client";  发送信息给客户端  
        send(sServer,sendMessage,strlen(sendMessage)+1,0);  
        char receiveMessage[5000];  
        nLeft = sizeof(receiveMessage);  
        ptr = (char *)&receiveMessage;  
        while(nLeft>0)  
        {    
            ret = recv(sServer, ptr, 5000, 0);  
            if (ret == SOCKET_ERROR)  
            {  
                printf("recv() failed!\n");  
                return 0;  
            }  
            if (ret == 0) 客户端已经关闭连接  
            {  
                printf("Client has closed the connection\n");  
                break;  
            }  
            nLeft -= ret;  
            ptr += ret;  
        }    


最后关闭全部的accept和sock中socket。closesocket(1),closesocket(2)。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值