c - Socket编程客户端服务器消息读写C

标签 c sockets pthreads mutex

我已经为客户端服务器模型编写了代码。如果我在程序中传递值但当我尝试通过传递地址来传递值时它工作正常。 我犯了很多我无法弄清楚的愚蠢错误。我还尝试使用 pthreads 概念创建 100 个线程,基本意图是当客户端 ping 我的服务器并发送消息服务器回显它并且它可以分配客户端发送的 100 个线程消息中的任何一个。但如何做到这一点......我仍在努力。

这是我的服务器代码:

#include <stdio.h>
#include <string.h>    
#include <stdlib.h>    
#include <sys/socket.h>
#include <arpa/inet.h> 
#include <unistd.h>    
#include <pthread.h>
#include <sys/ipc.h>
#include <sys/uio.h>
#define NTHREADS 100

void *connection_handler(void *);
pthread_t thread_id[NTHREADS];
pthread_mutex_t lock;
int service_count, sockfd,d1;
struct sockaddr_in server , client;

// Socket create
int sock_create( )
{
    sockfd= socket(AF_INET , SOCK_STREAM , 0);

    if (sockfd <0)
    {
        printf("Could not create socket");  
        return 1;
    }
    puts("Socket created");
    memset(&server,0,sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY;
    server.sin_port = htons( 2100);

}      
// Bind
int sock_bind()
{
    int b= bind(sockfd,(struct sockaddr *)&server , sizeof(server));
    if (b <0)
    {
        perror("Bind failed. Error");
        return 1;
    }
    puts("Bind");

}
// Listen
int sock_listen()
{
   listen(sockfd , 10);
}
//Connection accept
int sock_accept()
{
    int s = sizeof(struct sockaddr_in);
    d1= accept(sockfd, (struct sockaddr *)&client, (socklen_t*)&s);

    if (d1 < 0)
    {
        perror("accept failed");
        return 1;
    } 
    puts("Connection accepted");
}

int main(int argc , char *argv[])
{  int client_sock;
   sock_create();
   sock_bind();
   sock_listen();
   sock_accept();

    pthread_attr_t attr;
    int i,j;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    printf("Creating threads\n");

    int cli_sock=client_sock;

    for (i = 0; i < NTHREADS ; i++)
    {
        pthread_create(&(thread_id[i]), &attr, connection_handler, (void*) &cli_sock);
    }

    pthread_attr_destroy(&attr); //Free attribute, wait for the other threads
    for(j=0; j < NTHREADS; j++)
    {
        pthread_join( thread_id[j], NULL);
    }
    pthread_exit(NULL);
    return 0;
}

void *connection_handler(void *sfd)
{   
    int sock = d1;
    int read_size=0;
    char *message , client_message[2000];

    //Receive msg from client
    while( (read_size = recv(sock , client_message , 2000 , 0)) > 0 )
    {   
        client_message[read_size] = '\0';
        //back to client
        write(sock, client_message , strlen(client_message));
        memset(client_message,'\0',sizeof(client_message));
        memset(client_message, 0, 2000);    
    }
     if(read_size == 0)
    {
        puts("Client disconnected");
        fflush(stdout);
    }
    else if(read_size == -1)
    {
        perror("Recv failed");    
    }
    pthread_mutex_lock(&lock);
    service_count++;
    pthread_mutex_unlock(&lock);

    pthread_exit((void*) sfd);
    return 0;
}

我的客户端代码是:

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

int main(int argc , char *argv[])
{
    int sockfd;
    struct sockaddr_in servaddr;
    char msg[1000] , servaddr_reply[2000];


    if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) <0)
    {
        printf("Could not create socket\n");
        return 1;
    }
    puts("Socket created");

    servaddr.sin_family= AF_INET;
    servaddr.sin_port= htons(2100);
    servaddr.sin_addr.s_addr= inet_addr("10.205.28.13");

    if (connect(sockfd , (struct sockaddr *)&servaddr , sizeof(servaddr)) <0)
    {
        perror("Connection failed\n");
        return 1;
    }
    puts("Connected");

    while(1)
    {
        printf("Enter msg:");
        scanf("%s" , msg);

        if( send(sockfd , msg , strlen(msg) , 0) < 0)
        {
            puts("Send failed");
            return 1;
        }
         // server reply
        if( recv(sockfd, servaddr_reply , 2000 , 0) < 0)
        {
            puts("Recv failed");
            break;
        }
        puts("Echo: ");
        puts(servaddr_reply);              
    }
        close (sockfd);
        return 0;
}

现在,当我的客户端假设发送问候时,如果我输入消息 hi 服务器会再次回复 hello .... 无法弄清楚为什么?

最佳答案

另外,为什么要使用额外的变量来分配套接字描述符?像 int a, b, c, d 吗?你在哪里用过你在你的处理程序中只使用了全局变量 *d1 ,它没有被初始化,因为

int sock_accept(int *d1) 函数优先本地。

另外我在您的以下代码中看到了问题

int b = bind(sockfd, (struct sockaddr *) &server, sizeof(server));
               ^
               |............. where you initialized?

以下代码相同

int d = accept(sockfd, (struct sockaddr *) &client, (socklen_t*) &s);

我还看到下面的意思是更少的代码

  sock_create(&a);
  sock_bind(&b);
  sock_listen(&c);
  sock_accept(&d);

你在哪里使用了a,b,c,d?因为为了进行通信,您已经采用了 sockfd*d1

您不需要将任何变量地址传递给您的函数,只需如下所示简单

  sock_create();
  sock_bind();
  sock_listen();
  sock_accept();

你的代码应该是

int service_count, sockfd, d1;

// Socket create
int sock_create()
{
  sockfd = socket(AF_INET, SOCK_STREAM, 0);

  if (sockfd < 0)
  {
    printf("Could not create socket");
    return 1;
  }
  puts("Socket created");
  memset(&server, 0, sizeof(server));
  server.sin_family = AF_INET;
  server.sin_addr.s_addr = INADDR_ANY;
  server.sin_port = htons(2100);

}
// Bind
int sock_bind()
{
  int b = bind(sockfd, (struct sockaddr *) &server, sizeof(server));
  if (b < 0)
  {
    perror("Bind failed. Error");
    return 1;
  }
  puts("Bind");

}
// Listen
int sock_listen()
{
  listen(sockfd, 10);
}
//Connection accept
int sock_accept()
{
  int s = sizeof(struct sockaddr_in);
  d1 = accept(sockfd, (struct sockaddr *) &client, (socklen_t*) &s);

  if (d1 < 0)
  {
    perror("accept failed");
    return 1;
  }
  puts("Connection accepted");
}

现在你的处理程序应该是

void *connection_handler(void *sfd)
{
  int sock = d1;
  int read_size = 0;
  char *message, client_message[2000];

  //Receive msg from client
  while ((read_size = recv(sock, client_message, 2000, 0)) > 0)
  {
    client_message[read_size] = '\0';
    //back to client
    write(sock, client_message, strlen(client_message));
    memset(client_message, '\0', sizeof(client_message));
    memset(client_message, 0, 2000);
  }
  if (read_size == 0)
  {
    puts("Client disconnected");
    fflush(stdout);
  }
  else if (read_size == -1)
  {
    perror("Recv failed");
  }
  pthread_mutex_lock(&lock);
  service_count++;
  pthread_mutex_unlock(&lock);

  pthread_exit((void*) sfd);

  return 0;
}

关于c - Socket编程客户端服务器消息读写C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24055234/

相关文章:

c - 递归函数中的求和

c - 如果我使用 O_NDELAY,为什么 errno 会设置 EAGAIN?从 dev/tty 读取

统计C程序中的注释数量

c++:本地数组定义与 malloc 调用

javascript - 如何维护套接字事件内连接的每个用户的值(value)

Python 执行通过套接字接收的命令时出现问题

python - 有关 HCI 滤波器 socket 选项的详细信息?

c - 为什么这段代码运行没有任何输出(关于pthread)?

C: 多个 pthread 期间 fgets 错误

c - 线程本地存储 (TLS) - 编译器错误