zoukankan      html  css  js  c++  java
  • socket(一)

    相关链接:

    http://my.oschina.net/u/1378445/blog/340206?p=2&temp=1469158886336#blog-comments-list

    http://blog.csdn.net/kesalin/article/details/8798039

    http://blog.csdn.net/xa846213981/article/details/50998316

    服务器端:

    #import <Foundation/Foundation.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    int main(int argc, const char * argv[])
    {
        @autoreleasepool {
            //        1
            int err;
            //int socket(int addressFamily, int type,int protocol)
            //int close(int socketFileDescriptor)
            //socket 创建并初始化 socket,返回该 socket 的文件描述符,如果描述符为 -1 表示创建失败。
            //通常参数 addressFamily 是 IPv4(AF_INET) 或 IPv6(AF_INET6)。type 表示 socket 的类型,通常是流stream(SOCK_STREAM) 或数据报文datagram(SOCK_DGRAM)。protocol 参数通常设置为0,以便让系统自动为选择我们合适的协议,对于 stream socket 来说会是 TCP 协议(IPPROTO_TCP),而对于 datagram来说会是 UDP 协议(IPPROTO_UDP)。
            //close 关闭 socket。
            int fd=socket(AF_INET, SOCK_STREAM  , 0);
            BOOL success=(fd!=-1);
            //        1
            //   2
            if (success) {
                NSLog(@"socket success");
                //Socket address, internet style.
                struct sockaddr_in addr;
                /*
                 struct sockaddr_in {
                 __uint8_t    sin_len;
                 sa_family_t    sin_family;
                 in_port_t    sin_port;
                 struct    in_addr sin_addr;
                 char        sin_zero[8];
                 };
                 */
                memset(&addr, 0, sizeof(addr));
                addr.sin_len=sizeof(addr);
                addr.sin_family=AF_INET;
                //            =======================================================================
                addr.sin_port=htons(5668);
                //        ============================================================================
                addr.sin_addr.s_addr=INADDR_ANY;
                //int bind(int socketFileDescriptor,sockaddr *addressToBind,int addressStructLength)
                // 将 socket 与特定主机地址与端口号绑定,成功绑定返回0,失败返回 -1。
                //成功绑定之后,根据协议(TCP/UDP)的不同,我们可以对 socket 进行不同的操作:
                //UDP:因为 UDP 是无连接的,绑定之后就可以利用 UDP socket 传送数据了。
                //TCP:而 TCP 是需要建立端到端连接的,为了建立 TCP 连接服务器必须调用 listen(int socketFileDescriptor, int backlogSize) 来设置服务器的缓冲区队列以接收客户端的连接请求,backlogSize 表示客户端连接请求缓冲区队列的大小。当调用 listen 设置之后,服务器等待客户端请求,然后调用下面的 accept 来接受客户端的连接请求。
                err=bind(fd, (const struct sockaddr *)&addr, sizeof(addr));
                success=(err==0);
            }
            //   2
            //        ============================================================================
            if (success) {
                NSLog(@"bind(绑定) success");
                //TCP 是需要建立端到端连接的,为了建立 TCP 连接服务器必须调用 listen(int socketFileDescriptor, int backlogSize) 来设置服务器的缓冲区队列以接收客户端的连接请求,backlogSize 表示客户端连接请求缓冲区队列的大小
                err=listen(fd, 5);//开始监听
                success=(err==0);
            }
            //    ============================================================================
            //3
            if (success) {
                NSLog(@"listen success");
                //            while (true) {//进入循环
                struct sockaddr_in clientAddress;
                int peerfd;
                socklen_t addrLen;
                addrLen=sizeof(clientAddress);
                NSLog(@"prepare accept");
                //int accept(int socketFileDescriptor,sockaddr *clientAddress, int clientAddressStructLength)
                //接受客户端连接请求并将客户端的网络地址信息保存到 clientAddress 中。
                //当客户端连接请求被服务器接受之后,客户端和服务器之间的链路就建立好了,两者就可以通信了。
                peerfd=accept(fd, (struct sockaddr *)&clientAddress, &addrLen);
                success=(peerfd!=-1);
                //    ============================================================================
                if (success) {
                    NSLog(@"accept success,remote address:%s,port:%d",inet_ntoa(clientAddress.sin_addr),ntohs(clientAddress.sin_port));
                    char buf[1024];
                    ssize_t count;
                    size_t len=sizeof(buf);
                    
                    do {
                        //
                        NSLog(@"begin");
                        //int receive(int socketFileDescriptor,char *buffer, int bufferLength, int flags)
                        // 从 socket 中读取数据,读取成功返回成功读取的字节数,否则返回 -1。
                        //一旦连接建立好之后,就可以通过 send/receive 接口发送或接收数据了。注意调用 connect 设置了默认网络地址的 UDP socket 也可以调用该接口来发送数据。
                        count=recv(peerfd, buf, len, 0);
                        NSLog(@"end");
                        NSString* str = [NSString stringWithCString:buf encoding:NSUTF8StringEncoding];
                        NSLog(@"%@",str);
                        //
                        char bufsend[1024];
                        printf("input message:");
                        scanf("%s",bufsend);
                        //int send(int socketFileDescriptor, char *buffer, int bufferLength, int flags)
                        // 通过 socket 发送数据,发送成功返回成功发送的字节数,否则返回 -1。
                        //一旦连接建立好之后,就可以通过 send/receive 接口发送或接收数据了。注意调用 connect 设置了默认网络地址的 UDP socket 也可以调用该接口来接收数据。
                        send(peerfd, bufsend, 1024, 0);
                    } while (strcmp(buf, "exit")!=0);
                }
                //    ============================================================================
                close(peerfd);
            }
            //        }
            //3
        }
        return 0;
    }
    //int sendto(int socketFileDescriptor,char *buffer, int bufferLength, int flags, sockaddr *destinationAddress, int destinationAddressLength)
    // 通过UDP socket 发送数据到特定的网络地址,发送成功返回成功发送的字节数,否则返回 -1。
    //由于 UDP 可以向多个网络地址发送数据,所以可以指定特定网络地址,以向其发送数据。
    
    //int recvfrom(int socketFileDescriptor,char *buffer, int bufferLength, int flags, sockaddr *fromAddress, int *fromAddressLength)
    // 从UDP socket 中读取数据,并保存发送者的网络地址信息,读取成功返回成功读取的字节数,否则返回 -1 。
    //由于 UDP 可以接收来自多个网络地址的数据,所以需要提供额外的参数,以保存该数据的发送者身份。
    View Code

    客户端:

    //  kewai_SocketClient
    //
    #import <Foundation/Foundation.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #import <arpa/inet.h>
    int main(int argc, const char * argv[])
    {
        @autoreleasepool {
            //        1
            int err;
            //socket 创建并初始化 socket,返回该 socket 的文件描述符,如果描述符为 -1 表示创建失败。
            int fd=socket(AF_INET, SOCK_STREAM, 0);
            BOOL success=(fd!=-1);
            struct sockaddr_in addr;
            //        1
            //   2
            if (success) {
                NSLog(@"socket success");
                memset(&addr, 0, sizeof(addr));
                addr.sin_len=sizeof(addr);
                addr.sin_family=AF_INET;
                addr.sin_addr.s_addr=INADDR_ANY;
                err=bind(fd, (const struct sockaddr *)&addr, sizeof(addr));
                success=(err==0);
            }
            //   2
            //3
            if (success) {
                //============================================================================
                struct sockaddr_in peeraddr;
                memset(&peeraddr, 0, sizeof(peeraddr));
                peeraddr.sin_len=sizeof(peeraddr);
                peeraddr.sin_family=AF_INET;
                peeraddr.sin_port=htons(5668);
                //            peeraddr.sin_addr.s_addr=INADDR_ANY;
                peeraddr.sin_addr.s_addr=inet_addr("127.0.0.1");
                //            这个地址是服务器的地址,
                socklen_t addrLen;
                addrLen =sizeof(peeraddr);
                NSLog(@"connecting");
                //int connect(int socketFileDescriptor,sockaddr *serverAddress, int serverAddressLength)
                // 客户端向特定网络地址的服务器发送连接请求,连接成功返回0,失败返回 -1。
                //当服务器建立好之后,客户端通过调用该接口向服务器发起建立连接请求。对于 UDP 来说,该接口是可选的,如果调用了该接口,表明设置了该 UDP socket 默认的网络地址。对 TCP socket来说这就是传说中三次握手建立连接发生的地方。
                //注意:该接口调用会阻塞当前线程,直到服务器返回。
                err=connect(fd, (struct sockaddr *)&peeraddr, addrLen);
                success=(err==0);
                if (success) {
                    //                struct sockaddr_in addr;
                    err =getsockname(fd, (struct sockaddr *)&addr, &addrLen);
                    success=(err==0);
                    //============================================================================
                    //============================================================================
                    if (success) {
                        NSLog(@"connect success,local address:%s,port:%d",inet_ntoa(addr.sin_addr),ntohs(addr.sin_port));
                        char buf[1024];
                        ssize_t count;
                        do {
                            //
                            printf("input message:");
                            scanf("%s",buf);
                            send(fd, buf, 1024, 0);
                            
                            //
                            NSLog(@"begin");
                            count=recv(fd, buf, 1024, 0);
                            NSLog(@"end");
                            NSString* str = [NSString stringWithCString:buf encoding:NSUTF8StringEncoding];
                            NSLog(@"*****%@",str);
                            
                        } while (strcmp(buf, "exit")!=0);
                    }
                }
                else{
                    NSLog(@"connect failed");
                }
            }
            //    ============================================================================
            //3
        }
        return 0;
    }
    View Code
  • 相关阅读:
    gearman管理工具GearmanManager的安装与使用
    php使用gearman进行任务分发
    centos7下的FastDFS5.09的安装与使用
    centos7下的glusterfs的安装与使用
    centos7下keepalived1.3.4安装与使用
    centos7下haproxy1.7的使用与配置
    centos7下apache2.4反向代理
    centos7下Redis3的安装与使用
    php使用fputcsv进行大数据的导出
    php新增的一些特性
  • 原文地址:https://www.cnblogs.com/jingdizhiwa/p/5695566.html
Copyright © 2011-2022 走看看