Socket和数据库的一些使用

发表于:2015-5-04 09:59

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:sixindev    来源:51Testing软件测试网采编

  最近偶尔有时间,研究了下Socket的使用,虽然不简单,不过还是挺有意思,刚好咱们带头大哥需要我们发檄文,也罢,那就来一篇,废话不多说,直接入正题
struct sockaddr_in server_addr;
pthread_mutex_t mut;
struct kevent events[10];
//IP地址、端口和协议族
server_addr.sin_len = sizeof(struct sockaddr_in);
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERVER_PORT);
server_addr.sin_addr.s_addr = inet_addr(ipAddress);
bzero(&(server_addr.sin_zero),8);
//创建socket
int server_sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_sock_fd == -1) {
perror("socket error");
return NULL;
}
int on=1;
if((setsockopt(server_sock_fd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)))<0)
{
perror("setsockopt failed");
exit(EXIT_FAILURE);
}
//绑定socket
int bind_result = bind(server_sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (bind_result == -1) {
perror("bind error");
return NULL;
}
//监听
if (listen(server_sock_fd, BACKLOG) == -1) {
perror("listen error");
return NULL;
}
struct timespec timeout = {10,0};
//kqueue
int kq = kqueue();
if (kq == -1) {
perror("创建kqueue出错!\n");
exit(1);
}
struct kevent event_change;
EV_SET(&event_change, STDIN_FILENO, EVFILT_READ, EV_ADD, 0, 0, NULL);
kevent(kq, &event_change, 1, NULL, 0, NULL);
EV_SET(&event_change, server_sock_fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
kevent(kq, &event_change, 1, NULL, 0, NULL);
while (1) {
int ret = kevent(kq, NULL, 0, events, 10, &timeout);
if (ret < 0) {
printf("kevent 出错!\n");
continue;
}else if(ret == 0){
printf("kenvent 超时!\n");
continue;
}else{
//ret > 0 返回事件放在events中
for (int i = 0; i < ret; i++) {
struct kevent current_event = events[i];
//kevent中的ident就是文件描述符
if (current_event.ident == STDIN_FILENO) {
//标准输入
bzero(input_msg, BUFFER_SIZE);
fgets(input_msg, BUFFER_SIZE, stdin);
//输入 ".quit" 则退出服务器
if (strcmp(input_msg, QUIT_CMD) == 0) {
exit(0);
}
for (int i=0; i<CONCURRENT_MAX; i++) {
if (client_fds[i]!=0) {
send(client_fds[i], input_msg, BUFFER_SIZE, 0);
}
}
}else if(current_event.ident == server_sock_fd){
//有新的连接请求
struct sockaddr_in client_address;
socklen_t address_len;
int client_socket_fd = accept(server_sock_fd, (struct sockaddr *)&client_address, &address_len);
if (client_socket_fd > 0) {
int index = -1;
for (int i = 0; i < CONCURRENT_MAX; i++) {
if (client_fds[i] == 0) {
index = i;
client_fds[i] = client_socket_fd;
break;
}
}
if (index >= 0) {
EV_SET(&event_change, client_socket_fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
kevent(kq, &event_change, 1, NULL, 0, NULL);
printf("新客户端(fd = %d)加入成功 %s:%d \n",client_socket_fd,inet_ntoa(client_address.sin_addr),ntohs(client_address.sin_port));
/*客户端赋值*/
strcpy(client.ipAddress, inet_ntoa(client_address.sin_addr));
client.client_port = ntohs(client_address.sin_port);
client.client_ID = client_socket_fd;
/*收集客户端信息并且存储到列表中*/
//                            if (AddClient(client, &clientList) == false) {
//                                fprintf(stderr, "Problem allcating memory\n");
//                                break;
//                            }
//                            if(ListIsFull(&clientList))
//                            {
//                                puts("The list is now full.\n");
//                                break;
//                            }
//                            if(ListIsEmpty(&clientList))
//                            {
//                                printf("NO client Connection");
//                            }else
//                            {
//                                Traverse(&clientList, showClients);
//                            }
//                            printf("在线客户端人数:%d\n", ListClientCount(&clientList));
if(!QueueIsFull(&line))
{
client.client_ID = client_socket_fd;
client.client_port = ntohs(client_address.sin_port);
strcpy(client.ipAddress, inet_ntoa(client_address.sin_addr));
EnQueue(client, &line); //将客户端添加到队列中
char msg[250];
char wellcome[250];
sprintf(msg,"新客户端(fd = %d) 加入成功 %s:%d",client_socket_fd,inet_ntoa(client_address.sin_addr),ntohs(client_address.sin_port));
sprintf(wellcome, "WellComm To NB Socket Server System your fd is %d addr is %s and port is %d",client_socket_fd,inet_ntoa(client_address.sin_addr),ntohs(client_address.sin_port));
//给所有客户端发送消息,除了刚刚连接上的客户端之外
for(int i=0; i<QueueItemCount(&line); i++)
{
if(index != i)
{
send(client_fds[i], msg, BUFFER_SIZE, 0);
}else
{
send(client_fds[i], wellcome, BUFFER_SIZE, 0);
}
}
}
}else{
bzero(input_msg, BUFFER_SIZE);
strcpy(input_msg, "服务器加入的客户端数达到最大值,无法加入!\n");
send(client_socket_fd, input_msg, BUFFER_SIZE, 0);
printf("客户端连接数达到最大值,新客户端加入失败 %s:%d \n",inet_ntoa(client_address.sin_addr),ntohs(client_address.sin_port));
}
}
}else{
//处理某个客户端过来的消息
bzero(recv_msg, BUFFER_SIZE);
long byte_num = recv((int)current_event.ident,recv_msg,BUFFER_SIZE,0);
if (byte_num > 0) {
if (byte_num > BUFFER_SIZE) {
byte_num = BUFFER_SIZE;
}
recv_msg[byte_num] = '\0';
printf("客户端(fd = %d):%s\n",(int)current_event.ident,recv_msg);
char delims[] = " ";
char *result = NULL;
result = strtok(recv_msg, delims);
int k = 0;
while( result != NULL ) {
if(k==0)
{
strcpy(tableName, result);
}else if (k == 1)
{
strcpy(userID, result);
}
k++;
printf( "result is \"%s\n", result );
result = strtok( NULL, delims );
}
sendMessage(client_fds[0], tableName, userID, user, &line);
break;
}else if(byte_num < 0){
printf("从客户端(fd = %d)接受消息出错.\n",(int)current_event.ident);
}else{
EV_SET(&event_change, current_event.ident, EVFILT_READ, EV_DELETE, 0, 0, NULL);
kevent(kq, &event_change, 1, NULL, 0, NULL);
close((int)current_event.ident);
for (int i = 0; i < CONCURRENT_MAX; i++) {
if (client_fds[i] == (int)current_event.ident) {
Client *exitClient = (Client *)malloc(sizeof(Client));
exitClient->client_ID = (int)current_event.ident;
//                                selectClientWithFds((int)current_event.ident, &line);
//                                int count = selectAllCilent(&line);//查找所有在线客户端
//                           bool   del =  deleteClientFormList(&clientList, *exitClient);
//                                printf("%d\n",del);
//                                Traverse(&clientList, showClients);
//                                if(!ListIsEmpty(&clientList))
//                                {
//                                    printf("\n排序后的元素\n");
//                                    int desc = DescClientFromList(&clientList);
//                                    Traverse(&clientList, showClients);
//                                    printf("\n逆置后的元素\n");
//                                    Reverse(&clientList);
//                                    Traverse(&clientList, showClients);
//                                }
//                                printf("在线客户端人数:%d\n", ListClientCount(&clientList));
printf("客户端(fd = %d)退出了\n",(int)current_event.ident);
//                                printf("剩余在线客户端个数%d\n",count);
client_fds[i] = 0;
break;
}
}
}
}
}
}
}    return NULL;
}
void showClients(Client client)
{
//    printf("客户端 IP: %s, port is %d, fds is %d\n",client.ipAddress, client.port, client.fds);
}
//void sendClientStates(int clientCount,Queue *pq)
//{
//
//
//}
//对接收到的服务端消息进行处理,并且进行回应
void * sendMessage(int client_fds, char * message, char *userID, struct userTableInfo *userInfo, Queue *pq)
{
struct userMessage user = selectUserInfoWithUserID(message, userID);
printf("username is %s\n", user.name);
send(client_fds, user.name, BUFFER_SIZE, 0);
send(client_fds, user.user_id, BUFFER_SIZE, 0);
send(client_fds, user.birthday, BUFFER_SIZE, 0);
//    pthread_mutex_unlock(&mut);
return NULL;
}
21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号