通信模式
1.点对点:一对一得通信
2.客户机/服务器:一对多的通信
函数
#include <sys/socket.h>
int socket (int domain, int type, int protocol);
*/
struct sockaddr
{
sa_family_t sa_family;
char sa_data[14];
};
#include <sys/un.h>
struct sockaddr_un
{
sa_family_t sun_family;
char sun_path[];
};
#include <netinet/in.h>
struct sockaddr_in
{
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
};
struct in_addr
{
in_addr_t s_addr;
};
typedef uint32_t in_addr_t;
#include <sys/socket.h>
int bind (int sockfd, const struct sockaddr* addr,socklen_t addrlen);
#include <sys/socket.h>
int connect (int sockfd, const struct sockaddr* addr,socklen_t addrlen);
范例
server
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <netinet/in.h>
#include <assert.h>
#include <stdint.h>
#include "server_main.h"
#include "log.h"
#include "msgque.h"
#include "account.h"
#include "business.h"
#include "fileoper.h"
#include "slinkedlist.h"
#define PATH "/"
#define PROID1 100
#define PROID2 101
int32_t sockfd = 0;
bool run = true;
void init(void){
pLogFile = stdout;
LOG_DEBUG("1、LOG日志已打开...\n");
init_config();
LOG_DEBUG("2、配置加载中!...\n");
AccountList = slinked_list_create(ASIZE);
LOG_DEBUG("3、创建链表!...\n");
load_data();
LOG_DEBUG("4、链表数据加载中!...\n");
load_base();
LOG_DEBUG("5、基本配置加载中!...\n");
}
static void sigint_proc(int32_t sig){
LOG_DEBUG("服务器正在关闭!...\n");
close(sockfd);
if(save_data() != 0 || save_base() != 0){
LOG_ERROR("数据保存失败!\n");
return;
}else{
LOG_ERROR("数据保存成功!\n");
}
LOG_DEBUG("服务器关闭成功!...\n");
run = false;
exit(0);
}
void remove_client(int fd){
int32_t i;
pthread_rwlock_wrlock(&lock);
for(i=0;i<size_acc;i++){
if(fd == get_client[i].fd){
close(fd);
get_client[i] = get_client[--size_acc];
break;
}
}
pthread_rwlock_unlock(&lock);
}
void* trans(void *arg){
LOG_ERROR("%lu 线程链接\n",pthread_self());
Client cls = *(Client*)arg;
Msg msg = {};
pthread_rwlock_wrlock(&lock);
get_client[size_acc++] = cls;
pthread_rwlock_unlock(&lock);
Account *pact = NULL;
while(true){
int32_t ret = msg_recv(cls.fd,&msg);
if(ret == 0){
pthread_rwlock_wrlock(&lock);
LOG_ERROR("%lu 线程断开链接\n",pthread_self());
remove_client(cls.fd);
break;
}
int32_t msgsz = business_entry(&msg,&pact);
msg_send(cls.fd,&msg,msgsz);
}
}
void accept_client(int fd){
Client cls = {};
socklen_t len = sizeof(cls.addr);
pthread_t id;
int32_t ret = 0;
while(true){
cls.fd = accept(fd,(struct sockaddr*)&cls.addr,&len);
assert(cls.fd != -1);
ret = pthread_create(&id,NULL,trans,(void*)&cls);
assert(ret == 0);
}
}
void server_run(const char *ip,const char *port){
signal(SIGINT,sigint_proc);
init();
LOG_DEBUG("按CTRL+C关闭服务器!...\n");
int32_t sock = socket(AF_INET,SOCK_STREAM,0);
if(sock == -1){
perror("socket");
LOG_FATAL("socket is can't get!\n");
exit(1);
}
struct sockaddr_in server;
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(ip);
server.sin_port = htons(atoi(port));
socklen_t len = sizeof(server);
if(bind(sock,(struct sockaddr*)&server,len) < 0){
perror("bind");
LOG_FATAL("socket is can't bind!\n");
exit(2);
}
if(listen(sock,MAX_CLIENTS) < 0){
printf("listen error\n");
LOG_FATAL("socket is can't listen!\n");
exit(3);
}
accept_client(sock);
}
client
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <pthread.h>
#include <assert.h>
#include "client_main.h"
#include "log.h"
#include "msgque.h"
#include "useroper.h"
#define PATH "/"
#define PRO1 100
#define PRO2 101
bool run = true;
int32_t fd;
int32_t msgsr = 0;
static void* client_entry(void *arg){
Msg* msg =(Msg*)arg;
msgsr = read_msg(msg);
int32_t ret = msg_send(fd,msg,msgsr);
if(ret == -1 || msg->type == 0){
return;
}
ret = msg_recv(fd,msg);
analyze_msg(msg);
}
void client_run(const char *ip,const char *port){
pLogFile = stdout;
LOG_INFO("开始初始化!\n");
fd = socket(AF_INET,SOCK_STREAM,0);
if(fd == -1){
perror("socket");
return;
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(port));
addr.sin_addr.s_addr = inet_addr(ip);
socklen_t len = sizeof(addr);
int32_t ret = connect(fd,(const struct sockaddr *)&addr,len);
if(ret == -1){
perror("connect");
return;
}
Msg msg = {};
pthread_t id;
while(run){
ret = pthread_create(&id,NULL,client_entry,(void*)&msg);
assert(ret == 0);
pthread_join(id,NULL);
}
}