服务器增强版(TCP)
来源:互联网 发布:lms算法原理及推导 编辑:程序博客网 时间:2024/06/05 02:50
1) 服务器端存在的问题:
*recv会阻塞
解决方法:1、多线程技术
2、 超时返回
2)如何用accept获取客户端IP和端口号
3)TCP通信应用场景:注册统计信息、智能聊天、云计算
4)补充知识
计算机数据存储有两种字节优先顺序:高位字节优先和低位字节优先。Internet上数据以高位字节优先顺序在网络上传输,所以对于在内部是以低位字节优先方式存储数据的机器,在Internet上传输数据时就需要进行转换,否则就会出现数据不一致。
下面是几个字节顺序转换函数:
htonl():把32位值从主机字节序转换成网络字节序
htons():把16位值从主机字节序转换成网络字节序
ntohl():把32位值从网络字节序转换成主机字节序
ntohs():把16位值从网络字节序转换成主机字节序
#include <sys/types.h> #include <sys/socket.h>#include <arpa/inet.h>#include <stdio.h> #include <string.h>#include <stdlib.h>#include <errno.h>#include <pthread.h>#include <netinet/in.h>void* rcv_data(void* arg);void save_files(const char* str);pthread_mutex_t m;int main(){ pthread_mutex_init(&m,NULL);//创建套接字 int socket_listen=socket(AF_INET,SOCK_STREAM,0); int opt_val=1; setsockopt(socket_listen,SOL_SOCKET,SO_REUSEADDR,&opt_val,sizeof(opt_val)); //设置文件 //绑定地址 struct sockaddr_in myaddr; myaddr.sin_family = AF_INET; myaddr.sin_addr.s_addr=INADDR_ANY; myaddr.sin_port=htons(6666); if(-1==bind(socket_listen,(struct sockaddr*)&myaddr,sizeof(myaddr))) { perror("bind"); exit(-1); }//将套接字设置为监听状态 listen(socket_listen,5); struct timeval rcv_timeout;//设置超时为100ms rcv_timeout.tv_sec=0; rcv_timeout.tv_usec=100000; int sock_conn; struct sockaddr_in client_addr; socklen_t len; while(1)//一直监听 {//接受客户端连接请求 len=sizeof(client_addr); sock_conn=accept(socket_listen,(struct sockaddr*)&client_addr,&len); setsockopt(sock_conn,SOL_SOCKET,SO_RCVTIMEO,&rcv_timeout,sizeof(rcv_timeout));//设置超时时间 printf("%s:%d已近连接!\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port)); if(sock_conn==-1) { perror("accept"); continue; } pthread_t tid; if(0!=pthread_create(&tid,NULL,rcv_data,(void*)sock_conn)) { perror("pthread_create"); close(sock_conn); } }//7、关闭监听套接字 close(socket_listen); pthread_mutex_destroy(&m); return 0;}void* rcv_data(void* arg){ pthread_detach(pthread_self()); int sock_conn=(int)arg; //收发数据 char msg[100]; int ret; ret=recv(sock_conn,msg,sizeof(msg),0);//0表默认,不加额外控制 //阻塞到收到消息,或连接断开 if(ret>0) { msg[ret]='\0'; printf("客户端说:%s\n",msg); save_files(msg); } else if(ret==0) { printf("接收失败,连接断开\n"); } else { if(errno==EAGAIN || errno==EWOULDBLOCK) { printf("接收超时!\n"); } else { printf("其他错误\n"); } } strcpy(msg,"收到您的信息"); ret=send(sock_conn,msg,strlen(msg),0);//6、断开连接,即关闭连接套接字 close(sock_conn); return NULL;}void save_files(const char* str){ pthread_mutex_lock(&m);//保证下面三句话不被打断 FILE* fp=fopen("name.txt","a"); fprintf(fp,"%s\n",str); fclose(fp); pthread_mutex_unlock(&m);}//解决阻塞问题//1.主线程接电话,然后分配给其他线程receive//2.超时返回//端口复用//显示对方IP//当客户端send,而服务器端关闭了连接套接字时,服务器进程会收到13号信号,导致进程结束,为了避免这种情况,要用信号处理函数对信号处理。//应用:注册统计信息//群聊天室//云计算
阅读全文
0 0
- 服务器增强版(TCP)
- select版tcp服务器(python实现)
- TCP服务器(多线程)
- TCP/IP通信(服务器)
- TCP小型服务器(poll)
- 单进程select版-TCP服务器(python 版)
- 单进程epoll版-TCP服务器(python 版)
- 单进程gevent版-TCP服务器(python 版)
- Tcp服务器
- 'IOKING' TCP Transmission Server Engine ('云猴'©TCP通讯服务器引擎)(预告版)
- linux服务器安全增强(ssh和iptables)
- Erlang版TCP服务器对抗攻击解决方案
- Erlang版TCP服务器对抗攻击解决方案
- 基于TCP 的服务器、、客户端(socket)
- tornado做简单socket服务器(TCP)
- tornado做简单socket服务器(TCP)
- TCP并发服务器模型(一)
- TCP并发服务器模型(二)
- 自己实现智能指针
- 检测文件mime类型和模糊哈希
- 一张图学会git命令
- codeforces433DIV2.(Sep 7th 2017)
- 关于epoll版服务器的理解(Python实现)
- 服务器增强版(TCP)
- 面试之STAR法则
- XML配置文件导入dtd文件仍然没有自动提示问题的解决
- linux 入门
- JQuery中attr()和prop()用法和区别
- nginx安装第三方ngx_cache_purge模块,purge命令清除静态缓存
- setUserVisibleHint-- fragment真正的onResume和onPause方法
- 初学freertos第二课
- python pip 国内源