zoukankan      html  css  js  c++  java
  • c socket编程

    1、UDP

    (1)client.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <sys/socket.h>

    #define REMOTEPORT 4567
    #define REMOTEIP "127.0.0.1"//这是server端的IP,如在两台机器上测试,只需更改此IP为server端IP

    /*
    所在头文件:#include <strings.h>
    函数原型:extern void bzero(void *s, int n);
    函数功能:置字节字符串s的前n个字节为零且包括‘\0’。
    入口参数:字符串,整型。
    出口参数:无返回值。
    */

    /*
    所在头文件:#include <arpa/inet.h>
    函数原型:in_addr_t inet_addr(const char *cp);
    函数功能:将一个点间隔地址转换成一个in_addr。
    入口参数:点间隔地址字符串。
    出口参数:in_addr 型地址。
    */

    /*
    所在头文件:#include <unistd.h>
    函数原型:ssize_t read(int fd, void *buf, size_t count);
    函数功能:从文件流描述符fd中读数据到buf中,长度不超过count
    入口参数:文件流描述符,缓存,长度
    出口参数:读到的字符总长度。
    */

    /*
    所在头文件:#include < sys/types.h > #include < sys/socket.h >
    函数原型:int sendto (int s,void * msg,int len, unsigned int flags,struct sockaddr *to,int tolen);
    函数功能:将本机编号为s的套接字字符串msg发送给to套接字结构体所代表的地址及端口;
    入口参数:s--socket编号,msg--需要发送的字符串,len--发送的字符串长度,flags--一般置0,to--套接子结构体类型,tolen--套接字结构体长度;
    出口参数:传送成功,返回传送的字符个数;失败,返回-1。
    */

    int main(int argc,char *argv[])
    {
        int s,len;
        struct sockaddr_in addr;//套接字数据类型,用来存放一个套接字,这里是目的套接字
        int addr_len;
        char msg[256];   
        int i=0;
        /*if else创建本地即客户端套接字*/
        if(( s = socket(AF_INET,SOCK_DGRAM,0))<0) //创建套接字,返回套接字编号
        {
            perror("error");
            exit(1);
        }
        else
        {
            printf("socket created successfully!\n");
            printf("socket id:%d\n",s);
            printf("remote ip:%s\n",REMOTEIP);
            printf("remote port: %d\n\n",REMOTEPORT);
        }
        /*if else创建本地即客户端套接字*/

        addr_len=sizeof(struct sockaddr_in);
        bzero(&addr,sizeof(addr));
        /*外地即服务端套接字*/
        addr.sin_family=AF_INET;
        addr.sin_port=htons(REMOTEPORT);
        addr.sin_addr.s_addr=inet_addr(REMOTEIP);
        /*外地即服务端套接字*/

        while(1)
        {
            bzero(msg,sizeof(msg));

            printf("Please Input message\n");
            printf("The serial number of the message:%d\n",i);
            i++;
            len=read(STDIN_FILENO,msg,sizeof(msg));//从键盘(终端)键入msg

            sendto(s,msg,len,0,(struct sockaddr *)&addr,addr_len);//发送msg给目的套接字addr
            printf("Send message from client:%s",msg);

            len=recvfrom(s,msg,sizeof(msg),0,(struct sockaddr *)&addr,&addr_len);//接受目的套接字传来的msg

            printf("Received message from server:%s\n",msg);
        }

    }

    (2)server.c

    #include &lt;stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <sys/socket.h>

    #define LOCALPORT 4567

    int main(int argc,char *argv[])
    {
        int mysock,len;
        struct sockaddr_in addr;
        int i=0;
        char msg[256];
        int addr_len;
        /*创建本地即服务端套接字*/
        if((mysock=socket(AF_INET,SOCK_DGRAM,0))<0)
        {
            perror("error");
            exit(1);
        }
        else
        {
            printf("socket created successfully!\n");
            printf("socked id:%d\n",mysock);
        }
        /*创建本地即服务端套接字*/
        addr_len=sizeof(struct sockaddr_in);
        bzero(&addr,sizeof(addr));

        /*本地即server套接字属性*/
        addr.sin_family=AF_INET;
        addr.sin_port=htons(LOCALPORT);
        addr.sin_addr.s_addr=htonl(INADDR_ANY);//INADDR_ANY 0.0.0.0 即将地址清零,系统找到的是本机IP
        /*本地即server套接字属性*/
        /*绑定本地server套接字的端口和IP*/
        if(bind(mysock,(struct sockaddr *)&addr,sizeof(addr))&lt;0)
        {
            perror("error");
            exit(1);
        }
        else
        {
            printf("bind successfully!\n");       
            printf("local port:%d \n\n",LOCALPORT);
        }
        /*绑定本地server套接字的端口和IP*/

        while(1)
        {
            bzero(msg,sizeof(msg));
            len=recvfrom(mysock,msg,sizeof(msg),0,(struct sockaddr *)&addr,&addr_len);
            printf("The serial number of the message:%d\n",i);
            i++;

            printf("The message Received from client:%s",msg);
            printf("Received message length:%d\n",len);
            printf("Received message from:%s\n",inet_ntoa(addr.sin_addr));
            printf("Reply message from server:%s\n",msg);
            sendto(mysock,msg,len,0,(struct sockaddr *)&addr,addr_len);
        }
    }

    2.TCP

    (1)client.c

    #include &lt;stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <sys/stat.h>
    #include <fcntl.h>

    #define PORT 5678
    #define REMOTE_IP "127.0.0.1"

    int main()
    {
        int s;
        struct sockaddr_in addr;
        char mybuffer[256];

        if((s=socket(AF_INET,SOCK_STREAM,0))<0)
        {
            perror("socket");
            exit(1);
        }
        else
        {
            printf("socket created successfully!.\n");
            printf("socked id:%d\n",s);
        }

        bzero(&addr,sizeof(addr));
        addr.sin_family=AF_INET;
        addr.sin_port=htons(PORT);
        addr.sin_addr.s_addr=inet_addr(REMOTE_IP);

        if(connect(s,(struct sockaddr *)&addr,sizeof(addr))&lt;0)
        {
            perror("connect");
            exit(1);
        }
        else
        {
            printf("connected ok!\n");
            printf("remote ip:%s\n",REMOTE_IP);
            printf("remote port:%d\n",PORT);
        }

        recv(s,mybuffer,sizeof(mybuffer),0);
        printf("%s\n",mybuffer);
        while(1)
        {
            bzero(mybuffer,sizeof(mybuffer));
            read(STDIN_FILENO,mybuffer,sizeof(mybuffer));//从键盘读信息
            /*发送并接收数据(if else意思是发送成功则执行接收,发送失败则退出)*/
            if(send(s,mybuffer,sizeof(mybuffer),0)&lt;0)//发送从键盘读到的信息
            {
                perror("send");
                exit(1);
            }
            else
            {
                bzero(mybuffer,sizeof(mybuffer));
                recv(s,mybuffer,sizeof(mybuffer),0);//接收server端的信息
                printf("received from server:%s\n",mybuffer);
            }
            /*发送并接收数据(if else意思是发送成功则执行接收,发送失败则退出)*/
        }
    }

    (2)

    server.c

    #include &lt;stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>

    #define PORT 5678
    #define MAX 10

    /*面向连接套接字server端*/

    /*
    所在头文件:#include <sys/select.h>
    函数原型:int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
    函数功能:一个进程同时处理多个文件描述符是很常见的情况。
    入口参数:
    出口参数:1、正常情况返回就绪的文件描述符个数;2、timeout时长无设备准备好,返回0;3、若select被某个信号中断,返回-1,并设置errno为EINTR;4、若出错,则返回-1,并设置相应的errno。
    */
    int main()
    {
        int sockfd,newsockfd,is_connected[MAX],fd;
        struct sockaddr_in addr;
        int addr_len = sizeof(struct sockaddr_in);
        fd_set myreadfds;//定义文件描述符集合
        char msgbuffer[256];
        char msg[]="The message is from server:connected successfully.\n";
        /*创建本地套接字*/
        if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
        {
            perror("socket");
            exit(1);
        }
        else
        {   
            printf("socket created successfully!\n");
            printf("socket id:%d\n",sockfd);
        }
        /*创建本地套接字*/
        /*允许地址重用*/
        int ret,on;
        on=1;
        ret=setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
        /*允许地址重用*/

        /*本地套接子属性*/
        bzero(&addr,sizeof(addr));
        addr.sin_family=AF_INET;
        addr.sin_port=htons(PORT);
        addr.sin_addr.s_addr=htonl(INADDR_ANY);
        /*本地套接子属性*/

        /*绑定本地套接子端口和IP等属性*/
        if(bind(sockfd,(struct sockaddr *)&addr,sizeof(addr))&lt;0)
        {
            perror("connect");
        }
        else
        {
            printf("connected successfully!\n");
            printf("local port:%d\n",PORT);
        }
        /*绑定本地套接子端口和IP等属性*/

        /*server监听,等待client连接,最大连接数为3*/
        if(listen(sockfd,3)&lt;0)
        {
            perror("listen");
            exit(1);
        }
        else
        {
            printf("listening......\n");
        }
        /*server监听,等待client连接,最大连接数为3*/
        for(fd=0;fd&lt;MAX;fd++)
        {
            is_connected[fd]=0;
        }

        while(1)
        {
            FD_ZERO(&myreadfds);//文件描述符集合中所有位置0
            FD_SET(sockfd,&myreadfds);//将文件描述符的sockfd位置1(本地套接字位置1)
            for(fd=0;fd&lt;MAX;fd++)
            {
                if(is_connected[fd])
                {
                    FD_SET(fd,&myreadfds);
                }
            }
            if(!select(MAX,&myreadfds,NULL,NULL,NULL))
            {
                continue;
            }
            for(fd=0;fd&lt;MAX;fd++)   
            {
                if(FD_ISSET(fd,&myreadfds))           
                {   
                    if(sockfd==fd)
                    {
                        if((newsockfd=accept(sockfd,(struct sockaddr *)&addr,&addr_len))&lt;0)
                        {
                            perror("accept");
                        }
                        write(newsockfd,msg,sizeof(msg));//给客户端发送信息
                        is_connected[newsockfd]=1;
                        printf("connect from%s\n",inet_ntoa(addr.sin_addr));
                    }
                    else
                    {   
                        bzero(msgbuffer,sizeof(msgbuffer));
                        if(read(fd,msgbuffer,sizeof(msgbuffer))&lt;=0)
                        {
                            printf("connect closed.\n");
                            is_connected[fd]=0;
                            close(fd);
                        }
                        else
                        {
                            write(fd,msgbuffer,sizeof(msgbuffer));
                            printf("message:%s\n",msgbuffer);
                        }
                    }
                }
            }
        }
    }

    (3)运行

    gcc –o client.exe client.c

    gcc –o server.exe server.c

    在两个终端分别运行./client.c    ./server.c

    client.c终端输入字符串

    且先运行server

    套接字函数介绍

    1、socket函数

    #include &lt;sys/socket.h>

    int socket(int family,int type,int protocol);

    功能:

    创建一个套接口

    入口:

    family——指明协议族,一般是AF_INET(IPv4协议);

    type——有SOCK_STREAM、SOCK_DGRAM、SOCK_SEQPACKET、SOCK_RAW;

    protocol——IPPROTO_TCP  IPPROTO_UDP  IPPROTO_SCTP

    出口:

    正确,套接字字符描述符,非负整数;出错,-1

  • 相关阅读:
    牛客网-练习题
    牛客网-趋势科技-2020届校园招聘上机考试-1
    976. Largest Perimeter Triangle--Easy
    812. Largest Triangle Area--Easy
    123. Best Time to Buy and Sell Stock III--Hard
    1131. Maximum of Absolute Value Expression--Medium
    1103. Distribute Candies to People--Easy
    满足高并发的I/O Reactor线程模型 (附图,附代码)
    最简洁易懂的方式介绍I/O模型
    从鸿蒙OS的特性看华为应对封锁的策略
  • 原文地址:https://www.cnblogs.com/helloweworld/p/2699147.html
Copyright © 2011-2022 走看看