TCP套接字网络编程实例(二)
2017-07-21 15:48
363 查看
TCP套接字网络编程实例(二)
采用多线程实现客户端和服务器的聊天功能。OK,上代码。1.客户端部分:
/* * 文件:tcp_client.c * 内容:利用TCP实现客户端和服务器的实时聊天。 * 注 :服务器的端口号及IP,客户端的端口号及IP的输入通过main函数的argc和argv来实现。 * 未输入端口号的话使用默认端口号,服务器为1111,客户端为2222。 * 编译:gcc tcp_chat_client.c -o cli -lpthread * 运行:./cli 127.0.0.1 7788(注:这个是服务器端的地址和端口号) */ #include #include #include #include #include #include #include #include #include #include #include #define IP "127.0.0.1" #define SPORT 1111 #define CPORT 2222 #define MAXLEN 1024 void* myrecv(void* arg) { int sock_fd = 0,len = 0; char buf[MAXLEN] = {'\0'}; time_t t; sock_fd = *((int*)arg); while(1) { memset(buf,'\0',sizeof(buf)-1); len = recv(sock_fd,buf,sizeof(buf) - 1,0); if(len > 0) { t = time(NULL); printf("**********************************\n"); printf("&server:%s\n",buf); printf("**********************************\n"); printf("@%s\n",ctime(&t)); } else if(len < 0) { printf("recv msg errno,errno code = %d,errno msg = %s\n",errno,strerror(errno)); break; } else { printf("connect server error,it will be quit in 3 seconds later...\n"); sleep(3); exit(EXIT_FAILURE); } } } void* mysend(void* arg) { int sock_fd = 0,len = 0; char buf[MAXLEN] = {'\0'}; sock_fd = *((int*)arg); while(1) { memset(buf,'\0',sizeof(buf)); gets(buf); if(!strncasecmp(buf,"quit",4)) { printf("I will close the connect ...\n"); sleep(1); exit(EXIT_FAILURE); } len = send(sock_fd,buf,strlen(buf),0); if(len < 0) { printf("msg is:%s,send failer,errno is %d,errno message is:%s\n",buf,errno,strerror(errno)); break; } } } int main(int argc,char* argv[]) { int pid = 0,sock_fd = 0; socklen_t len; struct sockaddr_in their_addr; unsigned int their_port; char buf[MAXLEN] = {0}; pthread_t pthread1,pthread2; //创建socket if((sock_fd = socket(AF_INET,SOCK_STREAM,0)) < 0) { perror("socket error"); exit(EXIT_FAILURE); } //发送连接服务器的请求 memset(&their_addr,0,sizeof(their_addr)); their_addr.sin_family = AF_INET; if(argv[2] && argc >= 3) their_port = atoi(argv[2]); else their_port = SPORT; their_addr.sin_port = htons(their_port); if(argv[1] && argc >=2) { if(inet_aton(argv[1],(struct in_addr *)&their_addr.sin_addr.s_addr) == 0) { perror("argv[1]"); exit(EXIT_FAILURE); } } else their_addr.sin_addr.s_addr = inet_addr(IP); if(connect(sock_fd,(struct sockaddr*)(&their_addr),sizeof(their_addr)) == -1) { perror("connect error"); exit(EXIT_FAILURE); } printf("==============================================\n"); printf("connect success!\n"); printf("if you want to leave,please print 'quit'.\n"); printf("==============================================\n"); pthread_create(&pthread1,NULL,myrecv,(void*)&sock_fd); pthread_create(&pthread2,NULL,mysend,(void*)&sock_fd); pthread_join(pthread1,NULL); pthread_join(pthread2,NULL); close(sock_fd); //关闭套接字 return 1; }
2.服务器部分:
/* * 文件:tcp_server.c * 内容:利用TCP实现客户端和服务器的实时聊天。 * 注 :服务器的端口号及IP,客户端的端口号及IP的输入通过main函数的argc和argv来实现。 * 未输入端口号的话使用默认端口号,服务器为1111,客户端为2222。 * 编译:gcc tcp_server.c -o ser -lpthread * 运行:./ser 127.0.0.1 7788 5 */ #include #include #include #include #include #include #include #include #include #include #define SPORT 1111 #define CPORT 2222 #define IP "127.0.0.1" #define MAXLEN 1024 struct network_info { struct sockaddr addr; int addr_len; int sock; }target = {0,0,0}; void* myrecv(void* arg) { int new_fd = 0,len = 0; char buf[MAXLEN] = {'\0'}; time_t t; struct network_info netinfo; netinfo = *((struct network_info*)arg); new_fd = netinfo.sock; while(1) { memset(buf,'\0',sizeof(buf)-1); len = recv(new_fd,buf,sizeof(buf) - 1,0); if(len > 0) { t = time(NULL); printf("&client:%s @%s\n",buf,ctime(&t)); } else if(len < 0) { printf("recv msg error,error code = %d,error msg = %s\n",errno,strerror(errno)); break; } else { printf("client is quit\n"); close(new_fd); break; } } } void* mysend(void* arg) { int new_fd = 0,len = 0; char buf[MAXLEN] = {'\0'}; struct network_info netinfo; netinfo = *((struct network_info*)arg); new_fd = netinfo.sock; while(1) { memset(buf,'\0',sizeof(buf)); gets(buf); if(!strncasecmp(buf,"quit",4)) { printf("I will close the connect\n"); close(new_fd); exit(EXIT_FAILURE); } len = sendto(new_fd,buf,strlen(buf),0,(struct sockaddr*)(&(netinfo.addr)),netinfo.addr_len); if(len < 0) { printf("msg is:%s,send failer,errno is %d,errno message is:%s\n",buf,errno,strerror(errno)); break; } } } int main(int argc,char* argv[]) { int pid = 0,sock_fd = 0,new_fd = 0; socklen_t len; struct sockaddr_in self_addr,their_addr; unsigned int myport,lisnum; char buf[MAXLEN] = {'\0'}; char ip[17] = {'\0'}; time_t t; pthread_t pthread1,pthread2; if(argv[2] && argc >=3) myport = atoi(argv[2]); else myport = SPORT; if(argv[3] && argc >= 4) lisnum = atoi(argv[3]); else lisnum = 3; //创建套接字 sock_fd = socket(AF_INET,SOCK_STREAM,0); if(sock_fd < 0) { perror("socket error"); exit(EXIT_FAILURE); } //绑定自己的端口号 memset(&self_addr,0,sizeof(self_addr)); self_addr.sin_family = AF_INET; self_addr.sin_port = htons(myport); if(argv[1]) self_addr.sin_addr.s_addr = inet_addr(argv[1]); else self_addr.sin_addr.s_addr = INADDR_ANY; if(bind(sock_fd,(struct sockaddr*)&self_addr,sizeof(self_addr)) == -1) { perror("bind error"); exit(EXIT_FAILURE); } //监听 if(listen(sock_fd,lisnum) == -1) { perror("listen error"); exit(EXIT_FAILURE); } //接受客户端的连接请求 memset(&their_addr,0,sizeof(their_addr)); len = sizeof(their_addr); printf("wait for connect\n"); while(1) { if((new_fd = accept(sock_fd,(struct sockaddr*)&their_addr,&len)) == -1) { printf("len=%d,new_fd=%d\n",len,new_fd); perror("accept error"); exit(EXIT_FAILURE); } printf("=====================================================================\n"); printf("client connect ok\n"); printf("though i am a server,but if you want to shutdown,please print 'quit'.\n"); printf("=====================================================================\n"); memcpy(&(target.addr),&(their_addr),len); target.addr_len = len; target.sock = new_fd; //创建线程用于进程间通信 pthread_create(&pthread1,NULL,myrecv,(void*)&target); pthread_create(&pthread2,NULL,mysend,(void*)&target); } pthread_join(pthread1,NULL); pthread_join(pthread2,NULL); close(new_fd); close(sock_fd); //关闭套接字 return 0; }
结果:(交叉编译后也可用,那么加上串口编程,加上select,将结构体改为字符串,字符串数据加IP地址等等然后以专有协议形成“报文”,然后和设备以相同协议通讯。)
相关文章推荐
- python 网络编程 TCP套接字实例
- [python] 专题七.网络编程之套接字Socket、TCP和UDP通信实例
- VC++之网络编程三 TCP编程实例
- TCP/IP网络编程 学习笔记_8 --优雅地断开套接字连接
- C#网络编程TCP通信实例程序简单设计
- windows sock 网络编程基础知识--基本TCP套接字编程
- TCP/IP网络编程 学习笔记_8 --优雅地断开套接字连接
- Python网络编程之TCP与UDP协议套接字用法示例
- linux网络编程之套接字/TCP/IP
- 【Linux网络编程】原始套接字实例:MAC 头部报文分析
- 网络编程-TCP程序实例(文本大写转化器)
- Android开发菜鸟级入门5--网络编程之套接字TCP
- 【Python网络编程】利用Python进行TCP、UDP套接字编程
- Windows sockets网络开发-基本TCP套接字编程
- 【Linux网络编程】原始套接字实例:MAC 地址扫描器
- 我的网络编程学习之路——TCP(流)套接字的读和写
- 第四章 基本TCP套接字编程 第五章 TCP客户/服务器程序实例
- 网络通信TCP编程实例代码
- ACE网络编程笔记(2):IPC SAP、ACE_SOCKET和TCP/IP通信实例
- Linux网络编程:原始套接字编程及实例分析