socket C/C++编程(7)server端读取client端键入的数据
来源:互联网 发布:视频监控软件免费版 编辑:程序博客网 时间:2024/06/06 03:52
1. 服务器读取一次客户端编辑发送的数据
#ifdef WIN32 #include <windows.h>#else #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <stdlib.h> #include <arpa/inet.h>#endif#include <stdio.h>int main(int argc, char *argv[]){ // 初始化”ws2_32.lib” #ifdef WIN32 WSADATA ws; WSAStartup(MAKEWORD(2,2), &ws); #endif // 创建第一类socket int sock = socket(AF_INET,SOCK_STREAM,0); if(sock == -1){ printf("create sock error!\n"); return -1; } // TCP Server指定端口并设置服务端端口的属性,返回(sockaddr*)&saddr unsigned short port = 8080; // 默认端口号 if(argc > 1){ port = atoi(argv[1]); } sockaddr_in saddr; // 声明端口 saddr.sin_family = AF_INET; // TCPIP协议 saddr.sin_port = htons(port); // 绑定端口号, htons()之host-to-network saddr.sin_addr.s_addr = 0; //或htonl(0) 服务器接受的IP地址 0表示接受任意内外网IP // 绑定端口到指定的socket,输入(sockaddr*)&saddr if(bind(sock, (sockaddr*)&saddr, sizeof(saddr))!=0){ printf("OS bind socks to this port %d failed\n", port); return -2; } printf("OS bind this port %d to sockets successfully!\n", port); listen(sock, 10); // 允许用户连接函数(客户socket(一个客户一个socket),最大请求数队列的长度,) sockaddr_in caddr; // 结构体:存储客户端的相关信息:端口号和IP地址s socklen_t len = sizeof(caddr); int client = accept(sock,(sockaddr*)&caddr,&len); // 第二类socket: 创建一个socket专门读取缓冲区clients(这里缓冲区大小如上行listen代码所示为10) printf("accept client %d", client); char *ip = inet_ntoa(caddr.sin_addr); // 客户端IP地址转字符串 unsigned short cport = ntohs(caddr.sin_port);// 客户端端口号(网络字节序转本地字节序) printf("client ip: %s, port is %d\n", ip, cport); // 打印客户端连接信息 char buf[1024] = {0}; int lenRecv = recv(client,buf, sizeof(buf)-1,0); // server读取client端键入的数据(第二类socket的句柄,存储数据的地方,flag) printf("Recvd data: %s \n Len: %d \n", buf, lenRecv); // 服务器显示客户端键入的字符串长度 #ifdef WIN32 // 读取数据的第二类socket创建后要记得关闭 closesocket(client); #else close(client); #endif //#ifdef WIN32 // 端口的第一类socket,不再交互后也要记得关闭,先二后一时堆栈思想 // closesocket(sock); //#else // close(sock); //#endif getchar(); return 0;}
客户端发送数据,如下图,
服务端接收数据,如下图,
但是,问题是客户端只能发送一次。下一步,我们允许客户端多次发送,服务器端多次接收,直到收到客户端“quit”字符串为止。
2. 服务器持续读取客户端编辑发送的数据
#ifdef WIN32 #include <windows.h>#else #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <stdlib.h> #include <arpa/inet.h>#endif#include <stdio.h>#include <string.h>int main(int argc, char *argv[]){ // 初始化”ws2_32.lib” #ifdef WIN32 WSADATA ws; WSAStartup(MAKEWORD(2,2), &ws); #endif // 创建第一类socket int sock = socket(AF_INET,SOCK_STREAM,0); if(sock == -1){ printf("create sock error!\n"); return -1; } // TCP Server指定端口并设置服务端端口的属性,返回(sockaddr*)&saddr unsigned short port = 8080; // 默认端口号 if(argc > 1){ port = atoi(argv[1]); } sockaddr_in saddr; // 声明端口 saddr.sin_family = AF_INET; // TCPIP协议 saddr.sin_port = htons(port); // 绑定端口号, htons()之host-to-network saddr.sin_addr.s_addr = 0; //或htonl(0) 服务器接受的IP地址 0表示接受任意内外网IP // 绑定端口到指定的socket,输入(sockaddr*)&saddr if(bind(sock, (sockaddr*)&saddr, sizeof(saddr))!=0){ printf("OS bind socks to this port %d failed\n", port); return -2; } printf("OS bind this port %d to sockets successfully!\n", port); listen(sock, 10); // 允许用户连接函数(客户socket(一个客户一个socket),最大请求数队列的长度,) sockaddr_in caddr; // 结构体:存储客户端的相关信息:端口号和IP地址s socklen_t len = sizeof(caddr); int client = accept(sock,(sockaddr*)&caddr,&len); // 第二类socket: 创建一个socket专门读取缓冲区clients(这里缓冲区大小如上行listen代码所示为10) printf("accept client %d", client); char *ip = inet_ntoa(caddr.sin_addr); // 客户端IP地址转字符串 unsigned short cport = ntohs(caddr.sin_port);// 客户端端口号(网络字节序转本地字节序) printf("client ip: %s, port is %d\n", ip, cport); // 打印客户端连接信息 char buf[1024] = {0}; for(;;){ int lenRecv = recv(client,buf, sizeof(buf)-1,0); // server读取client端键入的数据(第二类socket的句柄,存储数据的地方,flag) if(lenRecv <= 0) break; buf[lenRecv] = '\0'; // 客户端键入数据的末尾两位赋值‘、0’ if(strstr(buf,"quit")!= NULL){ break; // 字符串匹配函数,匹配到用户发送了"quit" } printf("Recvd data: %s \n Len: %d \n", buf, lenRecv); // 服务器显示客户端键入的字符串长度 } #ifdef WIN32 // 读取数据的第二类socket创建后要记得关闭 closesocket(client); #else close(client); #endif //#ifdef WIN32 // 端口的第一类socket,不再交互后也要记得关闭,先二后一时堆栈思想 // closesocket(sock); //#else // close(sock); //#endif getchar(); return 0;}
客户端可以持续地发送数据,直到发送“quit”截止与服务器端的第二类socket,如下图,
服务器端持续地接受数据,如下图,
但是,现在有一个问题,就是两个或者两个以上clients同时接入,只有第一个client发送的数据能被服务器接收到,第二个client发送的数据是不被接收的。下一步,采用服务器端多线程同步获取clients的键入数据。
阅读全文
0 0
- socket C/C++编程(7)server端读取client端键入的数据
- socket C/C++编程(6)server之accept()函数创建新socket以单独读取缓存区某个client的连接信息(客户端的IP和端口,但是,不包括client端键入的数据)
- socket server.c & client.c
- socket C/C++编程(11)windows client端使用ip,port,通过connect()连接上linux server
- 经典 C语言 socket SERVER,CLIENT 端代码实现
- C Socket Programming server client
- Windows C语言 Socket编程 client端(客户端)--初级(简单版)
- Windows C语言 Socket编程 client端(客户端)--断线重连版
- Simple TCP Server Client Socket C
- linux c socket学习 server&client --->code
- C#——Socket:Client端
- client.c和server.c 网络套接字socket编程热身程序
- 【Socket编程】使用C++实现Server端和Client端
- C/S(Client–server model)编程思想(2)
- 学习 C# Socket 编程(一):Client 端的实现
- Windows C语言 Socket编程 server端(服务器)--初级(简单版)
- socket C/C++编程(8)server端多线程处理clients队列
- linux c socket client与server实例代码
- java报错:找不到或无法加载主类
- prim 堆优化
- mac命令行方式操作DNS
- Jaxb处理java对象和xml之间转换常用的annotation
- 关于f_open遇见的FR_DISK_ERR问题
- socket C/C++编程(7)server端读取client端键入的数据
- int main(int argc, char *argv[])问题(1)--概念和传数值
- shell判断全部都是数字(shell学习笔记六)
- ASP.NET MVC使用Echarts动态生成图表
- ImageLoader缓存图片到SD卡+清除缓存
- 移动app开发,固定图片div宽高,根据实际图片大小控制图片不变形
- <一>练习 仿AideTeach 软件(android)
- Android APN
- 关于C#迭代器与Unity的Coroutine