目录
2、如何给文件描述符设置非阻塞属性----fcntl() ----- man 2 fcntl
4、多路复用的函数接口-------select -----man 2 select
- #include
- #include
- int fcntl(int fd, int cmd, ... /* arg */ );
比如:
- int fd = open("xxx");
- int status = fcntl(fd, F_GETFL ); //得到文件描述符的状态
- status |= O_NONBLOCK ;//在原来的基础上新增非阻塞属性
- fcntl(fd, F_SETFL,status); //把变量status的状态设置到文件描述符中
例子2: 使用TCP通信 将其修改为非阻塞属性
- 1 #include<stdio.h>
- 2 #include <sys/socket.h>
- 3 #include <sys/types.h> /* See NOTES */
- 4 #include <netinet/in.h>
- 5 #include <arpa/inet.h>
- 6 #include <string.h>
- 7 #include <unistd.h>
- 8 #include <fcntl.h>
- 9 #define OWNADDR "192.168.14.3" //我自己电脑的ip地址
- 10 #define OWNPORT 20000 //我自己电脑的该程序的端口号
- 12 int main()
- 13 {
- printf("当前是服务器 IP:%s Port:%u\n",OWNADDR,OWNPORT); 14
- //1、买手机(建立套接字) 15
- int socketfd = socket(AF_INET, SOCK_STREAM, 0); 16
- if(socketfd == -1) 17
- { 18
- printf("没钱了....,失败\n"); 19
- return -1; 20
- } 21
- //因为服务器立马退出之后,端口号不会及时释放
- //此时如果服务器又马上运行,那么端口号会被占用,导致服务器分配端口号失败,连接失败 23
- //所以设置端口号可以复用 24
- int optval = 1; 25
- setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR,&optval, sizeof(optval)); 26
- 27
- //2、绑定自己的电话号码(绑定自己的IP地址 和端口号) 28
- //定义一个IPV4结构体变量,初始化自己的IP地址和端口号 29
- struct sockaddr_in ownAddr; 30
- ownAddr.sin_family = AF_INET;/*地址族 IPV4*/ 31
- ownAddr.sin_port = htons(OWNPORT); //htons 将本地端口号转为网络端口号 32
- ownAddr.sin_addr.s_addr = inet_addr(OWNADDR); //将本地IP地址转为网络IP地址 33
- 34
- bind(socketfd, (struct sockaddr *)&ownAddr,sizeof(struct sockaddr_in)); 35
- 36
- //3、设置铃声(监听) listen 37
- listen(socketfd,5); 38
- 39
- //4、坐等电话(阻塞接收客户端的连接) 40
- printf("等待客户端连接.......\n"); 41
- //定义一个IPV4结构体变量,存储连接上来的客户端的IP地址 和 端口号 42
- struct sockaddr_in clientAddr; 43
- //如果你要想要获取对方的IP地址和端口号,第三个参数必须把结构体的大小传递进去 44
- int len = sizeof(struct sockaddr_in); 45
- 46
- //给 socketfd设置非阻塞属性 47
- int status = fcntl(socketfd,F_GETFL);//得到这个套接字文件描述符的属性 48
- //将得到的文件描述符的全部属性 中的 其中一个属性设置成 非阻塞 49
- status |= O_NONBLOCK; 50
- int ret = fcntl(socketfd,F_SETFL,status);//把变量status的状态设置到文件描述符中 51
- if(ret == -1) 52
- { 53
- printf("fcntl error\n"); 54
- 55
- } 56
- while(1) 57
- { 58
- //此时是非阻塞,会一直不断地循环 59
- int newClientFd = accept(socketfd,(struct sockaddr*)&clientAddr,&len); 60
- if(newClientFd != -1) 61
- {
- //printf("有客户端连接上来了............\n"); 63
- //打印连接上来的客户端的IP地址和端口号,将网络字节序转为 本地字节序 64
- printf("连接上来的客户端IP:%s 端口
- 号:%u\n",inet_ntoa(clientAddr.sin_addr),ntohs(clientAddr.sin_port));
- 65
- } 66
- //printf("11111111111\n"); 67
- } 68
- 69
- //5、关闭 70
- close(socketfd); 71
- //close(newClientFd); 72
- 73
- return 0; 74
- 75 }
- 思路: 最多可以接受20个客户端连接
- ---> 用户连接成功 ---> 判断满人 --> 拒绝连接 --> 断开该用户 2
- ---> 用户连接成功 ---> 未满人 --> 保存套接字到数组 3
- 4
- 5 struct ciient{
- int clifd[1000]; //已连接的用户的套接字 6
- int count; //已连接用户的总数 7
- 8 }
- 9
- 10
- 非阻塞IO:不断询问这些已连接的用户以及是否有新的人连接过来! 11
- while(1) 12
- { 13
- int clifd[20]; ??? 有没有数据来? 14
- }
- 1 #include<stdio.h>
- 2 #include<stdio.h>
- 3 #include <sys/types.h> /* See NOTES */
- 4 #include <sys/socket.h>
- 5 #include <sys/socket.h>
- 6 #include <arpa/inet.h>
- 7 #include <unistd.h>
- 8 #include<stdlib.h>
- 9 #include <string.h>
- 10 #include <errno.h>
- 11 #include <signal.h>
- 12 #include <sys/wait.h>
- 13 #include <fcntl.h>
- 14
- 15 //#include <pthread.h>
- 16
- 17 #define SERVER_PORT 9999
- 18
- 19
- 20 struct client{
- int clientFd_Array[1000] ;//存储所有连接上来的客户端的套接字文件描述符 21
- int clientCount; //连接上来的客户端的总数 22
- 23 };
- 24
- 25
- 26 void sys_err(const char*err)
- 27 {
- fprintf(stderr,"%s\n",strerror(errno)); 28
- exit(0); 29
- 30 }
- 31
- 32
- 33 int main()
- 34 {
- int ret; 35
- struct sockaddr_in clientAddr;//存储连接上来的客户端的IP地址和端口号 36
- int len = sizeof(struct sockaddr_in); 37
- struct client clientManager; //客户端 结构体管理变量 38
- 39
- //初始化结构体 40
- clientManager.clientCount = 0; 41
- 42
- printf("服务器 Port:%d PID:%d \n",SERVER_PORT,getpid()); 43
- 44
- //1、建立套接字 45
- int socketFd = socket(AF_INET,SOCK_STREAM, 0); 46
- if(socketFd == -1){ 47
- sys_err("socket error"); 48
- } 49
- //端口复用 50
- int optval = 1; 51
- setsockopt(socketFd,SOL_SOCKET,SO_REUSEADDR,&optval, sizeof(optval)); 52
- 53
- //2、绑定自己的IP地址和端口号 54
- struct sockaddr_in serverAddr; 55
- serverAddr.sin_family = AF_INET; 56
- serverAddr.sin_port = htons(SERVER_PORT);//short 57
- serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); 58
- 59
- ret = bind(socketFd,(struct sockaddr*)&serverAddr,sizeof(struct sockaddr_in)); 60
- if(ret == -1){ 61
- sys_err("bind error"); 62
- } 63
- 64
- //3、设置监听 65
- listen(socketFd,128); 66
- 67
- //设置该监听套接字 为 非阻塞属性 68
- //第一步 先得到原来该套接字原来的属性 69
- int state = fcntl(socketFd,F_GETFL); 70
- //第二步 在原来的基础上新增 一个非阻塞 属性 71
- state |= O_NONBLOCK; // state = state | O_NONBLOCK 72
- //第三步 将 新的属性 设置回 文件描述符中 73
- fcntl(socketFd,F_SETFL,state); 74
- 75
- while(1){ 76
- //4、接收新的客户端连接.... 77
- int newClientFd = accept(socketFd, (struct sockaddr*)&clientAddr,&len); 78
- if(newClientFd > 0) //说明有客户端连接上来了 79
- { 80
- printf("有新的客户端连接上来 IP:%s Port:%hu newClientFd:%d\n", 81
- inet_ntoa(clientAddr.sin_addr), 82
- ntohs(clientAddr.sin_port), 83
- newClientFd); 84
- 85
- //将客户端文件描述符的属性 设置成 非阻塞属性 86
- //第一步 先得到原来该套接字原来的属性 87
- int state = fcntl(newClientFd,F_GETFL); 88
- //第二步 在原来的基础上新增 一个非阻塞 属性 89
- state |= O_NONBLOCK; // state = state | O_NONBLOCK 90
- //第三步 将 新的属性 设置回 文件描述符中 91
- fcntl(newClientFd,F_SETFL,state); 92
- 93
- 94
- //将每一个连接上来的客户端存储到结构体变量中 95
- clientManager.clientFd_Array[clientManager.clientCount] =
- newClientFd;
- 96
- clientManager.clientCount++; 97
- } 98
- 99
- //挨个轮询查看 连接上来的客户端 是否有数据到达 100
- for(int i=0; i<clientManager.clientCount; i++){ 101
- char buf[1024] = {0}; 102
- int ret = recv(clientManager.clientFd_Array[i],buf, sizeof(buf),
- 0);
- 103
- if(ret == 0) //客户端断开了 104
- { 105
- //printf("客户端退出了....\n"); 106
- //sleep(1); 107
- break; 108
- } 109
- else if(ret > 0) //有数据 来了,可以进行打印 110
- { 111
- printf("recv:%s\n",buf); 112
- } 113
- } 114
- 115
- 116
- } 117
- 118
- //关闭 119
- close(socketFd);
- return 0; 123
- 124 }
- #include <sys/select.h>
- 2 #include <sys/time.h>
- 3 #include <sys/types.h>
- 4 #include <unistd.h>
- int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct
- timeval *timeout); //poll epoll
- struct timeval {
- 2 long tv_sec; /* seconds 秒*/
- 3 long tv_usec; /* microseconds 微秒*/
- 4 };
- 5
- void FD_CLR(int fd, fd_set *set); //把文件描述符集合里fd清0 6
- int FD_ISSET(int fd, fd_set *set); //测试文件描述符集合里fd是否置1 7
- void FD_SET(int fd, fd_set *set); //把文件描述符集合里fd位置1 8
- void FD_ZERO(fd_set *set); //把文件描述符集合里所有位清0
- 返回值:
- 成功
- 有数据到达 ---->状态发生变化的文件描述符的总数
- 没有数据到达,超时-->0
- 失败 -1
- 注意:
- 1、select能监听的文件描述符个数受限于FD_SETSIZE,一般为1024,单纯改变进程打开的文件描述符
- 个数并不能改变select监听文件个数
- 2、解决1024以下客户端时使用select是很合适的,但如果链接客户端过多,select采用的是轮询模
- 型,会大大降低服务器响应效率
- 3、可以进行跨平台
- /*4_accept非阻塞IO轮训服务器*/
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- /*socket*/
- #include <sys/types.h> /* See NOTES */ //man 2 socket
- /*inet_addr*/
- #include <sys/socket.h> //man 3 inet_addr
- #include <netinet/in.h>
- #include <arpa/inet.h>
- /*fcntl*/
- #include <fcntl.h> //man 2 fcntl
-
- #define SERVER_IP "192.168.11.2"
- #define SERVER_PORT 60000
-
- int main(int argc,char **argv)
- {
- //创建套接字
- int socket_fd = socket(AF_INET,SOCK_STREAM,0);
- if(socket_fd < 0)
- {
- perror("socket fail");
- return -1;
- }
-
- //所以设置端口号可以复用,这两条语句放在 绑定bind 之前
- int optval = 1;
- setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR,&optval, sizeof(optval));
-
- //绑定
- struct sockaddr_in server_addr;
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = htons(SERVER_PORT);
- server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
- bind(socket_fd,(struct sockaddr *)&server_addr,sizeof(server_addr));
-
- //监听
- listen(socket_fd,20);
-
- //添加非阻塞属性到socket_fd套接字中
- int status = fcntl(socket_fd, F_GETFL); //得到文件描述符的状态-->F_GETFL
- status |= O_NONBLOCK ;//在原来的基础上新增非阻塞属性
- fcntl(socket_fd, F_SETFL,status); //把变量status的状态设置到文件描述符中
-
- //接收
- int socket_client;
- int client_cnt[20],cnt=0,j=0;
- //初始化客户端的套接字
- for(j=0;j<20;j++)
- {
- client_cnt[j] = -1;
- }
-
- struct sockaddr_in client_addr;
- socklen_t addrlen = sizeof(client_addr);
-
- int ret;
- char buf[1024] = {0};
-
- //在不开进程和线程的情况,同时能够接受多个客户端
- while(1)
- {
-
- //由于socket_fd套接字带有阻塞属性,所以导致accept函数阻塞
- socket_client = accept(socket_fd,(struct sockaddr *)&client_addr,&addrlen);
- if(socket_client != -1)
- {
- char *ip = inet_ntoa(client_addr.sin_addr);
- int port = ntohs(client_addr.sin_port);
- printf("有新的客户端上线 [ip:%s port:%d]\n",ip,port);
-
- //将socket_client设置为非阻塞属性存放在数组中
- int status = fcntl(socket_client, F_GETFL); //得到文件描述符的状态-->F_GETFL
- status |= O_NONBLOCK ;//在原来的基础上新增非阻塞属性
- fcntl(socket_client, F_SETFL,status); //把变量status的状态设置到文件描述符中
-
- //将所有的客户端套接字存放在数组中
- client_cnt[cnt++] = socket_client;
- //cnt表示的是数组里面有效的客户端套接字
- //printf("cnt = %d\n",cnt);
- }
-
- #if 0 //查看数组里面所有的客户端套接字(调试用)
- for(j=0;j<20;j++)
- {
- printf("%d ",client_cnt[j]);
- }
- printf("\n");
-
- printf("等待连接中....\n");
- sleep(1);
- #endif
-
- //遍历数组里面所有的套接字(循环接受每一个客户端发过来的数据)
- for(j=0;j<cnt;j++) //cnt是数组里面有效的套接字
- {
- memset(buf,0,sizeof(buf));
-
- //默认状态下recv这个函数是阻塞属性,但是现在的recv是非阻塞的
- ret = recv(client_cnt[j],buf,sizeof(buf),0);
- if(ret > 0) //只打印有效的数据
- printf("buf:%s ret:%d\n",buf,ret);
-
- }
- }
-
- //关闭套接字
- close(socket_fd);
- }
-
-
-
-
- /*5_accept非阻塞IO轮训服务器ip与端口*/
- #include <stdio.h>
- #include <unistd.h>
- #include <string.h>
- /*socket*/
- #include <sys/types.h> /* See NOTES */ //man 2 socket
- /*inet_addr*/
- #include <sys/socket.h> //man 3 inet_addr
- #include <netinet/in.h>
- #include <arpa/inet.h>
- /*fcntl*/
- #include <fcntl.h> //man 2 fcntl
-
- #define SERVER_IP "192.168.11.2"
- #define SERVER_PORT 60000
-
- struct client_info
- {
- int cli_socket;
- struct sockaddr_in cli_addr;
- };
-
- int main(int argc,char **argv)
- {
- //创建套接字
- int socket_fd = socket(AF_INET,SOCK_STREAM,0);
- if(socket_fd < 0)
- {
- perror("socket fail");
- return -1;
- }
-
- //所以设置端口号可以复用,这两条语句放在 绑定bind 之前
- int optval = 1;
- setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR,&optval, sizeof(optval));
-
- //绑定
- struct sockaddr_in server_addr;
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = htons(SERVER_PORT);
- server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
- bind(socket_fd,(struct sockaddr *)&server_addr,sizeof(server_addr));
-
- //监听
- listen(socket_fd,20);
-
- //添加非阻塞属性到socket_fd套接字中
- int status = fcntl(socket_fd, F_GETFL); //得到文件描述符的状态-->F_GETFL
- status |= O_NONBLOCK ;//在原来的基础上新增非阻塞属性
- fcntl(socket_fd, F_SETFL,status); //把变量status的状态设置到文件描述符中
-
- //初始化客户端的套接字
- int cnt = 0,j=0;
- struct client_info info[100];
- for(j=0;j<100;j++)
- info[j].cli_socket = -1;
-
- struct sockaddr_in client_addr;
- socklen_t addrlen = sizeof(client_addr);
-
- //接收
- int socket_client;
- int ret;
- char buf[1024] = {0};
- //在不开进程和线程的情况,同时能够接受多个客户端
- while(1)
- {
-
- //由于socket_fd套接字带有阻塞属性,所以导致accept函数阻塞
- socket_client = accept(socket_fd,(struct sockaddr *)&client_addr,&addrlen);
- if(socket_client != -1)
- {
- char *ip = inet_ntoa(client_addr.sin_addr);
- int port = ntohs(client_addr.sin_port);
- printf("有新的客户端上线 [ip:%s port:%d]\n",ip,port);
-
- //将socket_client设置为非阻塞属性存放在数组中
- int status = fcntl(socket_client, F_GETFL); //得到文件描述符的状态-->F_GETFL
- status |= O_NONBLOCK ;//在原来的基础上新增非阻塞属性
- fcntl(socket_client, F_SETFL,status); //把变量status的状态设置到文件描述符中
-
- //将所有的客户端套接字存放在数组中
- //cnt表示的是数组里面有效的客户端套接字
- info[cnt].cli_socket = socket_client;
- info[cnt].cli_addr = client_addr;
- cnt++;
- }
-
- #if 0 //查看数组里面所有的客户端套接字(调试用)
- for(j=0;j<20;j++)
- {
- printf("%d ",info[j].cli_socket);
- }
- printf("\n");
-
- printf("等待连接中....\n");
- sleep(1);
- #endif
-
- //遍历数组里面所有的套接字(循环接受每一个客户端发过来的数据)
- for(j=0;j<cnt;j++) //cnt是数组里面有效的套接字
- {
- memset(buf,0,sizeof(buf));
-
- //默认状态下recv这个函数是阻塞属性,但是现在的recv是非阻塞的
- /* ret = recv(client_cnt[j],buf,sizeof(buf),0);
- if(ret > 0) //只打印有效的数据
- printf("buf:%s ret:%d\n",buf,ret); */
-
- ret = recv(info[j].cli_socket,buf,sizeof(buf),0);
- if(ret > 0) //只打印有效的数据
- printf("[ip:%s port:%d]buf:%s ret:%d\n",
- inet_ntoa(info[j].cli_addr.sin_addr),
- ntohs(info[j].cli_addr.sin_port),
- buf,ret);
- }
- }
-
- //关闭套接字
- close(socket_fd);
- }
-
-
-
-
-
- /*6_使用多路复用select实现TCP服务器*/
- #include<stdio.h>
- #include<stdio.h>
- #include <sys/types.h> /* See NOTES */
- #include <sys/socket.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <unistd.h>
- #include<stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <signal.h>
- #include <sys/wait.h>
- #include <fcntl.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <unistd.h>
-
- #define SERVER_IP "192.168.11.2"
- #define SERVER_PORT 60000
-
- void sys_err(const char*err)
- {
- fprintf(stderr,"%s\n",strerror(errno));
- exit(0);
- }
-
- int main()
- {
- int ret,max_fd,i=0,imax=0;
- int client[FD_SETSIZE]; //存储所有客户端的文件描述符//该宏系统已经定义好了 文件描述符的总数 1024
-
- struct sockaddr_in clientAddr;//存储连接上来的客户端的IP地址和端口号
- int len = sizeof(struct sockaddr_in);
-
- printf("服务器 Port:%d PID:%d \n",SERVER_PORT,getpid());
-
- //1、建立套接字(监听套接字)
- int socket_fd = socket(AF_INET,SOCK_STREAM, 0);
- if(socket_fd == -1)
- {
- sys_err("socket error");
- //perror("bind"); //两种错误条释放作用一样
- }
- //端口复用
- int optval = 1;
- setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,&optval, sizeof(optval));
-
- //2、绑定自己的IP地址和端口号
- struct sockaddr_in server_addr;
- server_addr.sin_family = AF_INET;
- server_addr.sin_port = htons(SERVER_PORT);//short
- //server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //表示本机任意IP地址
- server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);
-
- ret = bind(socket_fd,(struct sockaddr*)&server_addr,sizeof(struct sockaddr_in));
- if(ret == -1)
- {
- sys_err("bind error");
- }
-
- //3、设置监听
- listen(socket_fd,128);
-
- //定义文件描述符集合
- fd_set rset,allset;
- //清空集合
- FD_ZERO(&allset);
-
- FD_SET(socket_fd, &allset); //把监听套接字 加入到集合中
- //最大的文件描述符,在没有客户端进来之前,最大的文件描述符最大值就是socket_fd
- max_fd = socket_fd;
-
- //初始化为 -1 给存放客户端套接字的数组初始化
- for(int k=0; k<FD_SETSIZE; k++)
- {
- client[k] = -1;
- }
-
- //设置阻塞的时间
- struct timeval t;
- t.tv_sec = 5;
- t.tv_usec = 0;
-
- while(1)
- {
- rset = allset; //每次循环的时候都需要重新设置select的集合
- //多路复用 ,同时监听 多个套接字文件描述符的状态 --阻塞监听
- //nready表示的是状态发生变化的文件描述符的总数,(不是里面存放了多少个描述符)
- int nready = select(max_fd+1,&rset, NULL,NULL, NULL);
- if(nready == -1)
- {
- perror("select error");
- break;
- }
-
- //程序走到这里,说明集合中的文件描述符的状态一定发生变化了
-
- //如果是监听套接字文件描述符发生变化了,说明一定是有新客户端连接上来了
- if(FD_ISSET(socket_fd, &rset))
- {
- //接收新的客户端
- int new_clientfd = accept(socket_fd, (struct sockaddr*)&clientAddr,&len);
-
- printf("有新的客户端连接上来 IP:%s Port:%hu new_clientfd:%d\n",
- inet_ntoa(clientAddr.sin_addr),
- ntohs(clientAddr.sin_port),
- new_clientfd);
-
- //把新的客户端文件描述符加入到集合中
- FD_SET(new_clientfd, &allset);
- //更新文件描述符最大值
- if(new_clientfd > max_fd)
- max_fd = new_clientfd;
-
- //将连接上来的客户端文件描述符 加入到 数组中
- for(i=0; i<FD_SETSIZE; i++)
- {
- if(client[i] <0 )
- {
- client[i] = new_clientfd;
- break;
- }
- }
-
- //imax = i;//存放客户端套接字数组里面的最大的下标值(可以通过这个值来记录你客户端数目)
-
- //说明该集合中只有监听套接字文件描述符发生变化
- if(--nready == 0)
- continue;
- }
-
- //程序走到这里,说明有客户端发送数据过来
- for(i=0; i<FD_SETSIZE; i++)
- {
- if(client[i] <0)
- continue;
-
- //说明该客户端发送数据过来了,
- //客户端套接字的状态就发生变化这句话if(FD_ISSET(client[i], &rset))就成立
- if(FD_ISSET(client[i], &rset))
- {
- char buf[1024] = {0};
- int ret = read(client[i],buf,sizeof(buf));
- if(ret == 0) //该客户端断开了
- {
- printf("有客户端断开了.....\n");
- close(client[i]);//关闭文件描述符
-
- FD_CLR(client[i],&allset);//将该客户端从 文件集合中删除
- client[i] = -1; //该文件描述符对应的数组位置置 -1
- }
-
- printf("recv:%s\n",buf);
- //说明所有发生变化的文件描述符 已经被我们处理完了,则退出
- if(--nready == 0)
- break;
- }
- }
- }
-
- //关闭
- close(socket_fd);
-
- return 0;
- }
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- /*socket*/
- #include <sys/types.h> /* See NOTES */
- #include <sys/socket.h>
- /*ip*/
- #include <netinet/in.h> //man 3 inet_addr
- #include <arpa/inet.h>
-
- //服务器的IP地址
- #define SERVER_IP "192.168.11.2"
- #define SERVER_PORT 60000
-
- int main(int argc,char **argv)
- {
- //建立套接字--socket
- int socket_fd;
- //AF_INET-->ipv4 SOCK_STREAM-->tcp
- socket_fd = socket(AF_INET,SOCK_STREAM,0);
- if(socket_fd < 0)
- {
- perror("socket fail");
- return -1;
- }
- printf("socket_fd = %d\n",socket_fd);
-
- //填充IP地址(服务器)--新结构体
- struct sockaddr_in server_addr;
- server_addr.sin_family = AF_INET; //ipv4
- server_addr.sin_port = htons(SERVER_PORT);//host to net(本机端口号转网络端口号)
- server_addr.sin_addr.s_addr = inet_addr(SERVER_IP);//将本机IP转换为网络IP
-
- //连接服务器
- int ret;
- ret = connect(socket_fd,(struct sockaddr *)&server_addr,sizeof(server_addr));
- if(ret < 0)
- {
- printf("connect fail\n");
- return -1;
- }
-
- //给服务器发送数据
- char buf[1024] = {0};
- while(1)
- {
- memset(buf,0,sizeof(buf));
- scanf("%s",buf);
- ret = send(socket_fd,buf,strlen(buf),0);
- printf("send success ret:%d\n",ret);
- }
-
- //关闭套接字
- close(socket_fd);
- return 0;
- }