群聊模拟

奋斗客户端

/*************************************************************************
	> File Name: client.c
	> Author: 联合作战实验室
	> Email: v.manstein@qq.com 
	> Created Time: Sat 25 Mar 2017 05:18:10 PM CST
 ************************************************************************/

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

int sockfd; // socket descriptor

void init_client(int sip, int port);	// init client
void start_client();					// send msg to server
void destroy_client(int signo);			// close client
void* rcvmsg(void* p);					// recv msg form server

int main(int argc, const char *argv[])
{
	int port, sip;

	if(argc < 3){
		printf("usage: %s serverip port.\n", argv[0]);
		return -1;
	}
	port = htons(atoi(argv[2]));
	sip = inet_addr(argv[1]);

	signal(SIGINT, destroy_client); // close client
	init_client(sip, port);
	start_client();

	return 0;
}

void init_client(int sip, int port)
{
	printf("connect server......\n");
	sleep(1);

	// 1.create socket
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == sockfd) {
		perror("sockfd"), exit(-1);
	}

	// 2.create communication object
	struct sockaddr_in serveraddr;
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = port;
	serveraddr.sin_addr.s_addr = sip;

	//3.connect server
	int res = connect(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));
	if(-1 == res) {
		perror("connect client error: "), close(sockfd), exit(-1);
	}
	printf("connect server success.\n");
}

void start_client(void)
{
	char name[100] = {};
	char buf[100] = {};
	char msg[200] = {};
	pthread_t tid;

	// 1.send msg to server.
	printf("Please input you net-name: ");
	scanf("%s", name);
	strcat(name, ":");

	// 2. create new thread to accept msg form server.
	pthread_create(&tid, 0, rcvmsg, 0); // recv msg form server
	// send msg to server.
	while(1) {
		printf("Please input you msg: "); // send msg.
		scanf("%s", buf);
		fflush(stdin);
		sprintf(msg, "%s%s", name, buf);
		send(sockfd, msg, strlen(msg), 0);
		memset(msg, 0, sizeof(msg));
		memset(buf, 0, sizeof(buf));
	}
}

void* rcvmsg(void* p)
{
	char buf[200] = {};
	while(1) {
		recv(sockfd, buf, sizeof(buf), 0);
		printf("\n%s\n", buf);
		memset(buf, 0, sizeof(buf));
	}
}

void destroy_client(int signo)
{
	printf("Closing client......\n");
	close(sockfd);
	sleep(1);
	exit(0);
}

奋斗服务器

/*************************************************************************
	> File Name: server.c
	> Author: 联合作战实验室
	> Email: v.manstein@qq.com 
	> Created Time: Sat 25 Mar 2017 06:01:20 PM CST
 ************************************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <signal.h>
#include <string.h>
#include "list.h"

int sockfd;			//socket descriptor
socklist *slist = NULL;	// all client socket fd list;

static void init_server(int sip, int port);		// init server
static void start_server(void);					// start server
static void destroy_server(int signo);			// close server
static void* rcvMsg(void* p);					// recv msg form client
static void sendMsgToAll(void* msg);			// send msg to all on line client

int main(int argc, const char* argv[])
{
	int sip, port;

	if(argc < 3) {
		printf("usage: %s serverip port\n", argv[0]);
		return -1;
	}

	sip = inet_addr(argv[1]);
	port = htons(atoi(argv[2]));

	signal(SIGINT, destroy_server);
	init_server(sip, port);
	start_server();

	return 0;
}

static void init_server(int sip, int port)
{
	printf("Initializing server...\n");
	sleep(1);
	
	slist = create_empty_linklist();
	//1. create socket
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(-1 == sockfd)
	{
		perror("socket server: "),exit(-1);
	}
	//2. communication object.
	struct sockaddr_in serveraddr = {};
	serveraddr.sin_family = AF_INET;
	serveraddr.sin_port = port;
	serveraddr.sin_addr.s_addr = sip;	
	//3. bind socket and socket address
	int res = bind(sockfd, (struct sockaddr*)&serveraddr, sizeof(serveraddr));
	if(-1 == res)
	{
		perror("bind server: "),exit(-1);
	}
	printf("bind success.\n");
	//4. wait for client connect.
	res = listen(sockfd, 100);
	if(-1 == res)
	{
		perror("listen server: "),exit(-1);
	}
	printf("Server is initialized.\n");
}

static void start_server(void)	
{
	printf("Starting server...\n");
	sleep(1);
	printf("Server is ready.\n");
	while(1)
	{
		//1.准备一个新地址用来接受客户端的地址
		struct sockaddr_in acvAddr;
		socklen_t len = sizeof(acvAddr);
		//2.响应客户端的请求,然后开辟新线程去响应客户端,为了腾出主线程继续响应新的客户端
		int resfd = accept(sockfd,(struct sockaddr*)&acvAddr,&len);
		if(-1 == resfd)
		{
			perror("accept server"),exit(-1);
		}

		//3.开辟新线程去处理客户端的消息
		pthread_t tid;
		pthread_create(&tid, 0, rcvMsg, &resfd);
	}
}		

static void destroy_server(int signo)	
{
	printf("Server closing...\n");
	close(sockfd);
	sleep(1);
	exit(0);
}	
static void* rcvMsg(void* p)
{
	char buf[100] = {};
	char temp[50] = {};
	char name[30] = {};
	char *bp = buf;
	int len = 0;
	int login_flag = 1;
	int tempFd = *(int*)p;
	
	while(1)
	{
		//不停地接受来自客户端的消息
		memset(buf, 0, sizeof(buf));
		int ret = recv(tempFd, buf, sizeof(buf), 0);
		if(login_flag) {
			// 取出冒号前面的网名
			while(*bp++ != ':') {
				len++;
			}
			strncpy(temp, buf, len);
			temp[len] = '\0';
			strcpy(name, temp);
			// 通知大家有人上线
			strcat(temp , " login.\n");
			sendMsgToAll(temp);
			// 首次登入计入在线链表
			insert_tail_linklist(slist, tempFd);
			login_flag = 0;
			bp = NULL;
		}
		if(ret < 0) {
			perror("recv server");	
		} else if(0 == ret) {
			printf("client %d exit.\n", tempFd);
			strcat(name, " log out.\n");
			remove_data_linklist(slist, tempFd);
			sendMsgToAll(name);
			break;
		}
		//把接受到的消息发送给所有客户端
		sendMsgToAll(buf);
	}
	pthread_exit(NULL);

}				
static void sendMsgToAll(void* msg)	
{
	char* datap = (char*)msg;
	socklist* temp = slist->next;
	while(temp) {
		send(temp->data, datap, strlen(datap), 0);
		temp = temp->next;
	}
}	









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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值