Linux多线程并发C/S模型

服务端:

/*************************************************************************
	> File Name: server.c
	> Author: ma6174
	> Mail: ma6174@163.com 
	> Created Time: 2020年08月02日 星期日 14时44分18秒
 ************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/wait.h>
#include <pthread.h>
#include <malloc.h>
const int N = 128;
static int num = 0;
struct node{
	struct sockaddr_in addr;
	int clientfd;
};
void sys_err(char *msg)
{
	perror(msg);
	exit(1);
}

void *do_work(void *arg)
{
	struct node *vel = (struct node*) arg;
	char buf[N];
	printf("new client join ip:%s port:%d number:%d\n",inet_ntoa(vel->addr.sin_addr),
		ntohs(vel->addr.sin_port),++num);
	memset(buf,'\0',sizeof(buf));
	while(1)
	{
		int ret = read(vel->clientfd,buf,N);
		if(ret != 0)
		printf("[ip : %s -- port : %d] data : %s\n",inet_ntoa(vel->addr.sin_addr),
			ntohs(vel->addr.sin_port),buf);
		else {
			printf("[ip : %s -- port : %d] is exit\n",inet_ntoa(vel->addr.sin_addr),
			ntohs(vel->addr.sin_port));
			break;
		}
		write(vel->clientfd,"Accept",N);
	}
	close(vel->clientfd);
	free(vel);
	return NULL;
}
int main(int argc, char const *argv[])
{
	if(argc < 3) sys_err("input error");
	int sfd,cfd;
	pthread_t rid;
	sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd == -1) sys_err("Create socket error");

	struct sockaddr_in server_addr,client_addr;
	bzero(&server_addr,sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = inet_addr(argv[1]);
	server_addr.sin_port = htons(atoi(argv[2]));
	socklen_t slen = sizeof(server_addr);

	int val = 1;  //加上这个能很好的解决端口复用的问题
    int ret = setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,(void *)&val,sizeof(int));
    if(ret == -1)
    sys_err("setsockopt error"),close(sfd);

	if(bind(sfd,(struct sockaddr*)&server_addr,slen) == -1)
	sys_err("bind error"),close(sfd);
	if(listen(sfd,N) == -1) 
	sys_err("listen error"),close(sfd);
	socklen_t clen = sizeof(client_addr);
	while(1)
	{
		
		cfd = accept(sfd,(struct sockaddr*)&client_addr,&clen);
		if(cfd == -1) sys_err("accept error"),close(sfd);
		
		struct node *a;
		a = (struct node*)malloc(sizeof(struct node));
		a->addr = client_addr;
		a->clientfd = cfd;
		if(pthread_create(&rid,NULL,(void *)do_work,(void *)a) != 0)
		sys_err("pthread create"),close(sfd);
		pthread_detach(rid);
	}
	close(sfd);
	return 0;
}

客户端:

/*************************************************************************
	> File Name: client.c
	> Author: ma6174
	> Mail: ma6174@163.com 
	> Created Time: 2020年08月01日 星期六 17时39分40秒
 ************************************************************************/

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

#define N 128

int main(int argc, char const *argv[])
{
	if(argc < 3) {
		perror("input ip and port\n");
		exit(1);
	}
	int sockfd;
	if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1)
	{
		fprintf(stdout,"Create socket error\n");
		exit(1);
	}
	struct sockaddr_in client_addr;
	client_addr.sin_family = AF_INET;
	client_addr.sin_addr.s_addr = inet_addr(argv[1]);
	client_addr.sin_port = htons(atoi(argv[2]));

	if(connect(sockfd,(struct sockaddr*)&client_addr,sizeof(client_addr)) == -1)
	{
		perror("connect error\n");
		exit(1);
	}
	char buf[N];
	char recv_buf[N];
	memset(buf,'\0',sizeof(buf));
	while(fgets(buf,N,stdin) != NULL)
	{
		memset(recv_buf,'\0',sizeof(recv_buf));

		write(sockfd,buf,strlen(buf));
		read(sockfd,recv_buf,sizeof(recv_buf));
		printf("server : %s\n",recv_buf);
		memset(buf,'\0',sizeof(buf));
	}
	close(sockfd);
	return 0;
}

Makefile:

CC = gcc
CFLAGS = -lm -Wall -g

all:server client

server:server.o
	$(CC) $(CFLAGS) -pthread server.o -o server

client:client.o
	$(CC) $(CFLAGS) client.o -o client
server.o:server.c
	$(CC) $(CFLAGS) -c -pthread server.c -o server.o
client.o:client.c
	$(CC) $(CFLAGS) -c client.c -o client.o
clear:
	rm *.o

测试结果:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

译制片~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值