客户端
/*************************************************************************
> 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);
}
![奋斗](http://static.blog.csdn.net/xheditor/xheditor_emot/default/struggle.gif)
/*************************************************************************
> 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;
}
}