Linux下C语音实现socket发送和接收的小程序,linuxsocket


1、什么是socket套接字

socket其实就是计算机通信的端口,可以实现两个计算机之间的通信的一个接口,应用程序在网络上传输就是通过这个借口实现。

socket分为三种类型:

字节流套接字(Stream Socket),最常用socket类型,TCP协议使用此类接口。提供面向连接(建立虚拟电路)、无差错、发送顺序一致、无记录边界和非重复的网络信包传输

数据报套接字(Datagram Socket),UDP协议使用此类接口,提供无连接服务,它以独立的信包进行网络传输,信包最大长度为32KB,传输不保证顺序性、可靠性和无重复性,它通常用于单个报文传输或可靠性不重复的场合。数据报套接字接口的一个重要特点是它保留了记录边界。

原始数据报套接字(Raw Socket),提供对网络下层通讯协议(eg:IP协议)的直接访问,一般不是提供给普通用户的,主要用于开发新的协议或者用于提取协议教隐蔽的功能

2、 客户服务器通信流程

 

  • 创建套接字

  #include <sys/types.h> /* See NOTES */

  #include <sys/socket.h>

  int socket(int domain, int type, int protocol);//返回sockfd

  函数定义:这个函数返回套接字描述符,它唯一标识一个socket,后续操作用它作为参数来进行一些读写操作,socket函数的三个参数分别为:

  返回值:创建新描述符正确返回0,错误返回-1,并有对应的errorno详情见 https://linux.die.net/man/2/socket

  • 绑定IP和port

  #include <sys/types.h>

  #include <sys/socket.h>

  int bind(int sockfd, const struct sockaddr *addr,

         socklen_t addrlen);

  返回值:创建新描述符正确返回0,错误返回-1,详情见 https://linux.die.net/man/2/bind

  • 监听连接

  #include <sys/types.h>

  #include <sys/socket.h>

  int listen(int sockfd, int backlog);

  返回值:创建新描述符正确返回0,错误返回-1,详情见 https://linux.die.net/man/2/listen

  • 接收连接

  #include <sys/types.h>

  #include <sys/socket.h>

  int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

  返回值:成功则返回一个非负的SOCKET类型的值,表示接收到的套接字描述符,错误返回-1,并有对应的errorno,详情见https://linux.die.net/man/2/accept

3、C 程序

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdint.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <error.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
int main(){
    struct sockaddr_in server_addr, client_addr;
    int socketserver;
    int err;
    int socketclient;as
    struct timeval timeout;
    char rcvbuf[100];
    char sedbuf[100000];
    timeout.tv_sec=5;
    timeout.tv_usec=0;
    //socket buff size
    int opt=100000;

    if((socketserver = socket(AF_INET,SOCK_STREAM,0)) == -1)
        return 1;
    //接受时限5s
    //setsockopt(socketserver, SOL_SOCKET,SO_RCVTIMEO, (char*)&timeout,sizeof(timeout));
    //发送时限5s
    //setsockopt(socketserver, SOL_SOCKET,SO_SNDTIMEO, (char*)&timeout,sizeof(timeout));
    //接收缓冲区
    setsockopt(socketserver, SOL_SOCKET, SO_RCVBUF, (const char*)&opt,sizeof(opt));
    //发送缓冲区
    setsockopt(socketserver, SOL_SOCKET, SO_SNDBUF, (const char*)&opt,sizeof(opt));
    //设置服务器地址信息设置
    server_addr.sin_family = AF_INET;                    //TCP
    server_addr.sin_port = htons(8080);                  //网络字节顺序采用大端模式
    server_addr.sin_addr.s_addr = INADDR_ANY;            //本地IP地址
    // server_addr.sin_addr.s_addr=htonl(127.0.0.1);
    printf("server port:%ld\n", ntohs(server_addr.sin_port));
    memset(server_addr.sin_zero,'\0',sizeof(server_addr.sin_zero));
    err=bind(socketserver, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
    if(err == -1){
        perror("bind error:");
        return 1;
     }
    if((err = listen(socketserver,10)) == -1){
        perror("listen error:");
        return 1;
     }
    while(1){
        int len = sizeof(struct sockaddr);
        head:
        if((socketclient = accept(socketserver,(struct sockaddr *)&client_addr,&len)) == -1){
           if(errno == 11){
            puts("timeout");
              goto head;
             }
            else{
            perror("accpet error:");
            return 1;
            }
        }
      write(socketclient,sedbuf,100000);
      printf("send sucess\n");
      // handle the connection of client
      while(1){
         memset(rcvbuf,'\0',100);
         len = read(socketclient,rcvbuf,40);
         if(len <=0){
               if(errno == EINTR || errno == EAGAIN)// except interruption XXX 92                
            continue; 
             else{
                 perror("client down:");
                 break;
              }
         }
           printf(" I received  %s\n",rcvbuf);
      }//while(1) handle the connection of client
  }//while(1) 
return 0;
}
View Code

 

相关内容