-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathudp_server.c
146 lines (99 loc) · 3.35 KB
/
udp_server.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
* Author: WangBoJing
* email: [email protected]
* github: https://github.com/wangbojing
*/
#include "udp.h"
int king_buffer_parser(int sockfd, U8 *buffer, U32 length, struct sockaddr_in *addr) {
U8 status = buffer[KING_PROTO_BUFFER_STATUS_IDX];
printf("king_buffer_parser --> %x\n", status);
switch (status) {
case KING_PROTO_LOGIN_REQ: {
#if 1
int old = client_count;
int now = old+1;
if(0 == cmpxchg((UATOMIC*)&client_count, old, now)) {
printf("client_count --> %d, old:%d, now:%d\n", client_count, old, now);
return KING_RESULT_FAILED;
}
#else
client_count = client_count+1;
int now = client_count;
#endif
U8 array[KING_CLIENT_ADDR_LENGTH] = {0};
addr_to_array(array, addr);
printf("login --> %d.%d.%d.%d:%d\n", *(unsigned char*)(&addr->sin_addr.s_addr), *((unsigned char*)(&addr->sin_addr.s_addr)+1),
*((unsigned char*)(&addr->sin_addr.s_addr)+2), *((unsigned char*)(&addr->sin_addr.s_addr)+3),
addr->sin_port);
table[now].client_id = *(U32*)(buffer+KING_PROTO_LOGIN_SELFID_IDX);
memcpy(table[now].addr, array, KING_CLIENT_ADDR_LENGTH);
break;
}
case KING_PROTO_HEARTBEAT_REQ: {
int client_id = *(unsigned int*)(buffer+KING_PROTO_HEARTBEAT_SELFID_IDX);
int index = get_index_by_clientid(client_id);
table[index].stamp = time_genrator();
break;
}
case KING_PROTO_CONNECT_REQ: {
int client_id = *(unsigned int*)(buffer+KING_PROTO_CONNECT_SELFID_IDX);
int other_id = *(unsigned int*)(buffer+KING_PROTO_CONNECT_OTHERID_IDX);
king_send_notify(sockfd, other_id, client_id);
break;
}
case NTY_RPORO_MESSAGE_REQ: {
U8 *msg = buffer+KING_RPORO_MESSAGE_CONTENT_IDX;
int client_id = *(unsigned int*)(buffer+KING_RPORO_MESSAGE_SELFID_IDX);
int other_id = *(unsigned int*)(buffer+KING_PROTO_MESSAGE_OTHERID_IDX);
printf(" from client:%d --> %s\n", client_id, msg);
#if 0
king_send_message(sockfd, other_id, buffer, length);
#endif
break;
}
}
return KING_RESULT_SUCCESS;
}
int main(int argc, char *argv[]) {
printf(" This is a UDP Server\n");
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("socket");
exit(0);
}
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(argv[1]));
addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
perror("bind");
exit(1);
}
char buffer[KING_BUFFER_LENGTH] = {0};
struct sockaddr_in c_addr;
int n;
int length = sizeof(struct sockaddr_in);
while(1) {
n = recvfrom(sockfd, buffer, KING_BUFFER_LENGTH, 0, (struct sockaddr*)&c_addr, &length);
if (n > 0) {
buffer[n] = 0x0;
printf("%d.%d.%d.%d:%d say: %s\n", *(unsigned char*)(&c_addr.sin_addr.s_addr), *((unsigned char*)(&c_addr.sin_addr.s_addr)+1),
*((unsigned char*)(&c_addr.sin_addr.s_addr)+2), *((unsigned char*)(&c_addr.sin_addr.s_addr)+3),
c_addr.sin_port, buffer);
int ret = king_buffer_parser(sockfd, buffer, n, &c_addr);
if (ret == KING_RESULT_FAILED) continue;
buffer[KING_PROTO_BUFFER_STATUS_IDX] += 0x80;
n = sendto(sockfd, buffer, n, 0, (struct sockaddr*)&c_addr, sizeof(c_addr));
if (n < 0) {
perror("sendto");
break;
}
} else if (n == 0) {
printf("server closed\n");
} else {
perror("recv");
break;
}
}
return 0;
}