weixin_慕哥3021856 的学生作业:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BACKLOG 3 // 监听队列的长度
void *do_thread_client(void *arg)
{
ssize_t rbytes = 0, sbytes = 0;
char buffer[1024] = {0};
int cfd = *(int *)arg;
for (;;)
{
memset(buffer, 0, sizeof(buffer));
rbytes = recv(cfd, buffer, sizeof(buffer), 0);
if (rbytes == -1)
{
perror("[ERROR] recv()");
pthread_exit(NULL);
}
else if (rbytes > 0)
{
sbytes = send(cfd, buffer, strlen(buffer), 0);
if (sbytes == -1)
{
perror("[ERROR] send()");
pthread_exit(NULL);
}
}
else if (rbytes == 0)
{
printf("Connection closed.The client is offline.\n");
close(cfd);
pthread_exit(NULL);
}
printf("buffer: %s\n", buffer);
}
}
int main(int argc, const char *argv[])
{
int sockfd, cfd, ret;
struct sockaddr_in server_addr, client_addr;
pthread_t tid;
if (argc != 3)
{
fprintf(stderr, "Usage: %s \n", argv[0]);
return -1;
}
socklen_t len = sizeof(struct sockaddr_in);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
perror("[ERROR] socket()");
exit(EXIT_FAILURE);
}
bzero(&server_addr, sizeof(struct sockaddr_in));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = inet_addr(argv[1]);
server_addr.sin_port = htons(atoi(argv[2]));
ret = bind(sockfd, (const struct sockaddr *)&server_addr, sizeof(struct sockaddr));
if (ret == -1)
{
perror("[ERROR] bind()");
exit(EXIT_FAILURE);
}
ret = listen(sockfd, BACKLOG);
if (ret == -1)
{
perror("[ERROR] listen()");
exit(EXIT_FAILURE);
}
printf("Server listening...\n");
for (;;)
{
bzero(&client_addr, sizeof(client_addr));
cfd = accept(sockfd, (struct sockaddr *)&client_addr, &len);
if (cfd == -1)
{
perror("[ERROR] accept()");
exit(EXIT_FAILURE);
}
printf("Connection established. Client ip: %s, port: %d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
ret = pthread_create(&tid, NULL, do_thread_client, (void *)&cfd);
if (ret != 0)
{
fprintf(stderr, "[ERROR] pthread_create(): %s\n", strerror(ret));
exit(EXIT_FAILURE);
}
pthread_detach(tid);
}
close(sockfd);
return 0;
}