socket使用的demo(并没有设置非阻塞)
server:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <netdb.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <pthread.h>
#include <string>
using namespace std;
# define BUFFER_SIZE 1001
int deal_new_conn(int* p_connfd, struct sockaddr* p_req_addr,socklen_t* p_addr_len);
int main(int argc, char *argv[])
{
// 生成socket的地址 (ip port等)
char nAddr[20] = "127.0.0.1"; // 指定ip
int nPort = 9012; // port
struct in_addr addr;
if (inet_aton("127.0.0.1", &addr) < 0) //得到网络字节序的IP
{
printf("[ERROR] addr %s:%d is invalid\n", nAddr, nPort);
return -1;
}
struct sockaddr_in serv_addr;
memset(&serv_addr, '0', sizeof(serv_addr)); //地址初始化清空
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = addr.s_addr;
serv_addr.sin_port = htons(nPort);
// 生成监听的socket_fd (file describe)
int listenfd = 0, connfd = 0;
// listenfd = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0); // 非阻塞 这里设置noblock后accept就为非阻塞函数,accpt不到就返回-1
listenfd = socket(AF_INET, SOCK_STREAM , 0); //生成socket
// 绑定fd socket
if(bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1)
{
printf("[ERROR] bind error!");
return -1;
}
// 开始监听 fd
if(listen(listenfd, 10) == -1) // 设置连接队列的长度 为 10
{
printf("[ERROR] listen return false;");
return 0;
}
printf("start waiting connect.\n");
while(1)
{
//收到请求
struct sockaddr req_addr = { 0 };
socklen_t in_addr_len = sizeof (req_addr);
// 从监听的fd的队列中取一个接收到的connect, 返回这个connect的fd
connfd = accept(listenfd, &req_addr, &in_addr_len); // 接受到一个connect 返回fd
printf("\n\n=======\nnew client connected.\n");
deal_new_conn(&connfd, &req_addr, &in_addr_len);
}
} // server.c 服务端
int deal_new_conn(int* p_connfd, struct sockaddr* p_req_addr,socklen_t* p_addr_len)
{
printf("start deal_new_conn...\n");
// 收到请求后返回数据的buffer
char sendBuff[1025];
memset(sendBuff, '0', sizeof(sendBuff));
int connfd = *p_connfd;
struct sockaddr req_addr = *p_req_addr;
socklen_t addr_len = *p_addr_len;
// 设置非阻塞
// int flags = fcntl(connfd, F_GETFL);
// fcntl( connfd, F_SETFL, flags|O_NONBLOCK);
// 取请求来源的ipport
char hbuf[100], sbuf[100];
if (getnameinfo(&req_addr, addr_len, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);
// 读请求内容多次读
char recbuff[BUFFER_SIZE + 1];
string rec;
printf("===start read_data\n");
for(;;)
{
int result_len = read(connfd,recbuff, BUFFER_SIZE);
// if(result_len == -1 && (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN))
// {
// usleep(1);
// printf("|%d", result_len);
// continue;
// }
if(result_len > 0)
{
recbuff[result_len] = '\0';
rec += recbuff;
if(result_len != BUFFER_SIZE)
{
printf("(break result_len != BUFFER_SIZE)\n");
break;
}
printf("(continue)\n");
continue;
}
printf("(break result_len <=0 )\n");
break;
}
printf("[size:%d] ret:|%s|\n",rec.size(), rec.c_str());
printf("===end read_data\n");
// 处理数据
sleep(3); //阻塞三秒
time_t ticks;
ticks = time(NULL); // 返回当前时间
snprintf(sendBuff, sizeof(sendBuff), "%.24s\r\n", ctime(&ticks)); // 把结果输入到返回数据的buffer
// 返回数据
write(connfd, sendBuff, strlen(sendBuff)); // 写入返回数据
close(connfd); //关闭当前连接
printf("end deal_new_conn...\n");
return 0;
}
server代码有点问题,如果read的内容刚好是buffer的整数倍时,会卡在最后一次read,,还没找到问题,,不过问题不大,socket常跟epoll共同使用,会设置为非阻塞, 循环读的方式会改变不会有这种问题。
client就比较简单了
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<arpa/inet.h>
# include <unistd.h>
#define MAXLINE 4096
int main(int argc, char** argv)
{
int sockfd, n,rec_len;
char recvline[4096], sendline[4096]="qwertqwert1";
char buf[MAXLINE];
struct sockaddr_in servaddr;
if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ){
printf("create socket error: %s(errno: %d)\n", strerror(errno),errno);
exit(0);
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9012);
if( inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr) <= 0 ){
printf("inet_pton error for 127.0.0.1\n");
exit(0);
}
if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0 ){
printf("connect error: %s(errno: %d)\n",strerror(errno),errno);
exit(0);
}
printf("send msg to server: \n");
// fgets(sendline, 4096, stdin);
if( send(sockfd, sendline, strlen(sendline), 0) < 0 )
{
printf("send msg error: %s(errno: %d)\n", strerror(errno), errno);
exit(0);
}
if((rec_len = recv(sockfd, buf, MAXLINE,0)) == -1) {
perror("recv error");
exit(1);
}
buf[rec_len] = '\0';
printf("Received : %s ",buf);
close(sockfd);
exit(0);
}