linux下使用socket实现点对点通信的实验(server to client)

服务端监听两个端口,然后由客户端连接,没端都有一个发送线程和接受线程专门负责发送和接受

服务端流程:创建socket,绑定port(要先填充网络地址结构体),监听port,accept连接,然后进行数据传输

客户端流程:创建socket,填充服务端网络地址,连接服务端对应端口,然后进行数据传输


服务端代码

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


#define BUFLEN 1000
#define SEND_PORT 4000
#define RECV_PORT 4001
#define LISTEN_NUM 10


///set an connection, sockfd is the fd of socket, confd is the fd of one connetction
void  set_conn(int *sockfd, int *confd,int port)

    struct sockaddr_in s_addr, c_addr;
    socklen_t len;
    /*建立socket*/
    if((*sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror("socket");
        exit(errno);
    }


    //fill the address
    memset(&s_addr,0,sizeof(s_addr));
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(port);
    s_addr.sin_addr.s_addr = INADDR_ANY;


    ///set the port as a reuseable port
    int opt = 1;
    setsockopt(*sockfd,SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));


    ///bind
    if((bind(*sockfd, (struct sockaddr*) &s_addr,sizeof(struct sockaddr))) == -1)
    {
        perror("bind");
        exit(errno);
    }


    ///listen
    if(listen(*sockfd,LISTEN_NUM) == -1)
    {
        perror("listen");
        exit(errno);
    }


    ///accept
    len = sizeof(struct sockaddr);
    if((*confd = accept(*sockfd,(struct sockaddr*) &c_addr, &len)) == -1)
    {
        perror("accept");
        exit(errno);
    }
}

///发送线程
void* th_send(void* arg)
{
    int sockfd, confd;
    char buf[BUFLEN];
    set_conn(&sockfd,&confd,SEND_PORT);
    while(1)
    {
       fgets(buf,BUFLEN,stdin);
       if(!strcmp(buf,"exit"))
       {
              printf("exiting\n");
              close(sockfd);
              close(confd);
              return 0;
       }
       if( send(confd,buf,strlen(buf),0) == -1)
       {
       perror("消息发送失败");
       exit(errno);
       }
    }
}

///接收线程
void* th_recv(void* arg)
{
    int sockfd, confd;
    char buf[BUFLEN];
    set_conn(&sockfd,&confd,RECV_PORT);
    while(1)
    {
      memset(buf,0,BUFLEN);
    switch(recv(confd,buf,BUFLEN,0))
    {
    case -1: ///error occurred
        perror("接受消息失败");
        exit(errno);
    case 0:  ///peer  has  performed  an orderly shutdown.
        printf("客户端退出了,聊天终止");
        return;
    default:  /// receive succssed
        printf("client:%s",buf);
    }
}
}


int main()
{
    pthread_t tid_send,tid_recv;        

    pthread_create(&tid_send,NULL,th_send,NULL);///发送线程
    pthread_create(&tid_recv,NULL,th_recv,NULL);///接收线程


    pthread_join(tid_send,NULL);
    pthread_join(tid_recv,NULL);
    return 0;
}

客户端代码

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


#define BUFLEN 10000
#define SEND_PORT 4001
#define RECV_PORT 4000


int get_conn(int port)
{
    int sockfd;
    struct sockaddr_in s_addr;
    socklen_t len;


    /*建立socket*/
    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
    {
        perror("socket");
        exit(errno);
    }


    /*设置服务器端口*/
    memset(&s_addr,0,sizeof(s_addr));
    s_addr.sin_family = AF_INET;
    s_addr.sin_port = htons(port);
    s_addr.sin_addr.s_addr = inet_addr("127.0.0.1");


    /*连接服务器*/
    if(connect(sockfd,(struct sockaddr*)&s_addr,sizeof(struct sockaddr)) == -1)
    {
        perror("connect");
        exit(errno);
    }
    return sockfd;
}


void* th_send(void* arg)
{


    char buf[BUFLEN];
    int confd;
    int ret;
    confd = get_conn(SEND_PORT);
    while(1)
    {
         fgets(buf,BUFLEN,stdin);
         if(!strcmp(buf,"exit"))
         {
              close(confd);
              printf("exiting\n");
              return;
         }
          if( send(confd,buf,strlen(buf),0) == -1)
         {
            printf("return %d\n",ret);    
            perror("消息发送失败");
            exit(errno);
         }
    }
}


void* th_recv(void* arg)
{
    char buf[BUFLEN];
    int confd;
    confd = get_conn(RECV_PORT);
    while(1)
    {
       memset(buf,0,BUFLEN);
    switch(recv(confd,buf,BUFLEN,0))
    {
    case -1: ///error occurred
        perror("接受消息失败");
        exit(errno);
    case 0:  ///peer  has  performed  an orderly shutdown.
        printf("server退出了,聊天终止");
        return;
    default:  /// receive succssed
        printf("server:%s",buf);
    }
}
}


int main()
{
    pthread_t tid_send;
    pthread_t tid_recv;

    pthread_create(&tid_send,NULL,th_send,NULL);
    pthread_create(&tid_recv,NULL,th_recv,NULL);
    
    pthread_join(tid_send,NULL);
    pthread_join(tid_recv,NULL);
    return 0;
}

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。