socket阻塞型服务器与客户端实现

socket阻塞型服务端实现

#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <signal.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
//服务器端
 
void *fun_thrReceiveHandler(void *socketInfo);
void *fun_thrAcceptHandler(void *socketListen);
void *fun_id(void*on);

 
typedef struct MySocketInfo{
    int socketCon;
    char *ipaddr;
    uint16_t port;
}_MySocketInfo;
 
// 客户端数组
struct MySocketInfo arrConSocket[10];
int conClientCount = 0;
 
// 接受客户端线程列表
pthread_t arrThrReceiveClient[10];
int thrReceiveClientCount = 0;
 
int main()
{
    
    int on=1;
    printf("开始socket\n");
//创建套接字
    
    int socketListen = socket(AF_INET, SOCK_STREAM, 0);
 printf("socketListen= %d\n" ,socketListen);
    if(socketListen < 0)
    {
        printf("创建失败\n");
        exit(-1);
    }
   else
    {
        printf("创建套接字成功\n");
    }
//通讯准备    
    struct sockaddr_in server_addr;
    bzero(&server_addr,sizeof(struct sockaddr_in));
    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    server_addr.sin_port=htons(2000); 
   int temp=1;
   int socketset3= setsockopt(socketListen, SOL_SOCKET, SO_REUSEADDR, &temp, sizeof(temp));
  if(socketset3<0)
  {
     perror("setsockopt");
     exit(-1);

  }



//本地地址与套接口捆绑
    if(bind(socketListen, (struct sockaddr *)&server_addr,sizeof(struct sockaddr)) != 0)
    {
        perror("绑定ip地址、端口号失败\n");
        exit(-1);
    }
    else
    {
        printf("绑定ip地址,端口号\n");
    }
 // 将套接字设为监听模式,等待队列最大长度为10
    if(listen(socketListen, 10) != 0){
        printf("开启监听失败\n");
        exit(-1);
    }
    else
     {
        printf("开启监听成功\n");
    }
     
    pthread_t thrAccept;  
    pthread_create(&thrAccept,NULL,fun_thrAcceptHandler,&socketListen);
    pthread_detach(thrAccept );//子线程与父线程分离开
    

        pthread_t id = 0;
        pthread_create(&id,NULL,fun_id,&on);
        pthread_detach(id);
        

while(1)
{
       
        printf("当前有接受数据线程多少个:%d\n",thrReceiveClientCount);
 
 //向客户端发送数据      
        char userStr[30] = {'0'};
        scanf("%s",userStr);
// 退出
        if(strcmp(userStr,"q") == 0)
        {
            printf("用户选择退出!\n");
            break;
        }

        if(conClientCount <= 0)
        {
            printf("没有客户端连接\n");
        }
        else
       {

    
            int i;
            for(i=0; i<conClientCount; i++)
              {
//把输入内容写入发送客户端的数组中
                int sendMsg_len = send(arrConSocket[i].socketCon,userStr,300,0);
          //  printf("发送客户端的数据最大字节数:%d\n", sendMsg_len);
                if(sendMsg_len > 0)
               {
                    printf("向%s:%d发送成功\n",arrConSocket[i].ipaddr,arrConSocket[i].port);
                }
                else
                {
                    printf("向%s:%d发送失败\n",arrConSocket[i].ipaddr,arrConSocket[i].port);
                }
            }
        }
 
        sleep(0.5);
 }
 
    
    return 0;
}

void *fun_id(void*on)
{

     printf("error\n");

}
 //与客户端连接
void *fun_thrAcceptHandler(void *socketListen)
 {
    while(1)
     {
        int sockaddr_in_size = sizeof(struct sockaddr_in);
        struct sockaddr_in client_addr;
        bzero(&client_addr,sizeof(struct sockaddr_in));
        int _socketListen = *((int *)socketListen);
        //创建一个与客户端连接的套接字
        int socketCon = accept(_socketListen, (struct sockaddr *)(&client_addr), (socklen_t *)(&sockaddr_in_size));
        printf("socketCon=%d\n",socketCon);
        if(socketCon < 0)
        {

            printf("连接失败\n");
        }
        else
        {
            printf("连接成功 ip: %s:%d\r\n",inet_ntoa(client_addr.sin_addr),client_addr.sin_port);
        }
        printf("连接套接字为:%d\n",socketCon);
        
       struct timeval stTimeout;
       stTimeout.tv_sec = 10;
       stTimeout.tv_usec = 0;
//套接口设置选项
      int socketset1= setsockopt(socketCon, SOL_SOCKET, SO_SNDTIMEO, (char *)&stTimeout, sizeof(struct timeval));
       int socketset2= setsockopt(socketCon, SOL_SOCKET, SO_RCVTIMEO, (char *)&stTimeout, sizeof(struct timeval));
        if(socketset2<0)
    {
       printf("1111111\n");
     }
    else if(socketset2==0)
   {
      printf("222222\n");
   }
   else
   {
    printf("33333\n");
   }
      
       _MySocketInfo socketInfo;
        socketInfo.socketCon = socketCon;
        socketInfo.ipaddr = inet_ntoa(client_addr.sin_addr);
        socketInfo.port = client_addr.sin_port;
        arrConSocket[conClientCount] = socketInfo;
        conClientCount++;
        printf("连接了%d个用户\n",conClientCount);
 
        pthread_t thrReceive = 0;
        pthread_create(&thrReceive,NULL,fun_thrReceiveHandler,&socketInfo);
        pthread_detach(thrReceive);
        arrThrReceiveClient[thrReceiveClientCount] = thrReceive;
        thrReceiveClientCount++;
        
        sleep(0.5);
    }
 
 
}
 //接收客户端发来的数据
void *fun_thrReceiveHandler(void *socketInfo)
{
	char buffer[30];
	int buffer_length;
	_MySocketInfo _socketInfo = *((_MySocketInfo *)socketInfo);

      

    while(1)
 {
    	
    	bzero(&buffer,sizeof(buffer));
 //读取出来的数据放在缓存区中
        buffer_length = recv(_socketInfo.socketCon,buffer,300,0);
        if(buffer_length == 0)
        {
           printf("%s:%d 客户端关闭\n",_socketInfo.ipaddr,_socketInfo.port);
            conClientCount--;
            break;
        }
       else if(buffer_length < 0)
        {
            printf("接受客户端数据失败\n");
            
        }
        buffer[buffer_length] = '\0';
        printf("%s:%d 说:%s\n",_socketInfo.ipaddr,_socketInfo.port,buffer);
 
        
    }
    
    return NULL;
}

socket阻塞型客户端

#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <signal.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
//客户端阻塞
typedef struct MySocketInfo{
    int socketCon;
    unsigned long ipaddr;
    unsigned short port;
}_MySocketInfo;
 
void *fun_thrReceiveHandler(void *socketCon);

 
int main()
{
    printf("开始socket\n");
    
    int socketCon = socket(AF_INET, SOCK_STREAM, 0);
    if(socketCon < 0)
    {
        printf("创建TCP连接套接字失败\n");
        exit(-1);
    }
    
    struct sockaddr_in server_addr;
    bzero(&server_addr,sizeof(struct sockaddr_in));
    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
    server_addr.sin_port=htons(2000);
    struct timeval stTimeout;
    stTimeout.tv_sec=5;
    stTimeout.tv_usec=0;
   int setsocktmp1=setsockopt(socketCon, SOL_SOCKET, SO_SNDTIMEO, (char *)&stTimeout, sizeof(struct timeval));
   int   setsocktmp2= setsockopt(socketCon, SOL_SOCKET, SO_RCVTIMEO, (char *)&stTimeout, sizeof(struct timeval));
   if(setsocktmp2<0)
    {
       printf("1111111\n");
     }
    else if(setsocktmp2==0)
  {
     printf("222222\n");
     printf("errno=%d",errno);
     printf("error:%s\n",strerror(errno));
   }
  
      
    int res_con = connect(socketCon,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr));
  if(errno!=EINPROGRESS)
{
   printf("errno!=EINPROGRESS\n");
}
    if(errno==EINPROGRESS)
{
   printf("errno==EINPROGRESS\n");
}

    if(res_con != 0){
        printf("连接失败\n");
        printf("res_con=%d\n",res_con);

 //     exit(-1);
    }
 else 
{
    printf("连接成功,连接结果为:%d\n",res_con);
 }   
    pthread_t thrReceive;
    pthread_create(&thrReceive,NULL,fun_thrReceiveHandler,&socketCon);
    pthread_detach(thrReceive);
   //   printf("setsocktmp2= %d",setsocktmp2);

    while(1)
{
         
        char userStr[300] = {'0'};
        scanf("%s",userStr);
        if(strcmp(userStr,"q") == 0){
            printf("退出!\n");
            break;
        }
        // 发送消息
       
        int sendMsg_len = send(socketCon,userStr,300,0);
        if(sendMsg_len > 0){
            printf("发送成功,服务端套接字:%d\n",socketCon);
        }else{
            printf("发送失败\n");
        }
 
    }
   
    close(socketCon);
    return 0;
}
 
void *fun_thrReceiveHandler(void *socketCon)
{
   pthread_detach(pthread_self());//子线程自己分离自己线程
    while(1)
    {

        char buffer[30];
        int _socketCon = *((int *)socketCon);
        int buffer_length = recv(_socketCon,buffer,300,0);

        if(buffer_length == 0)
        {
            printf("服务器端异常关闭\n");
            exit(-1);
        }
       else if(buffer_length < 0){
            printf("接受服务器数据失败\n");
            break;
        }
        buffer[buffer_length] = '\0';
        printf("服务器说:%s\n",buffer);
        

    }
    
    return NULL;
}
 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值