#include <arpa/inet.h>
#include <asm-generic/socket.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdint.h>
#include <strings.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#define PORT 1234
#define MAX_QUE_CONN_NM 5
#define BUFFER_SIZE 1024
void config_socket_addr_afinet(struct sockaddr_in *addr,uint16_t port,const char* saddr){
if(addr == NULL){
printf("%s: Error >> addr is Null\n",__func__);
exit(1);
}
addr->sin_family = AF_INET;
addr->sin_port = htons(port);
addr->sin_addr.s_addr = (saddr == NULL)?INADDR_ANY:inet_addr(saddr);
bzero(addr->sin_zero,8);
}
void clear_socket_addr(struct sockaddr_in *addr){
bzero(addr,sizeof(struct sockaddr_in));
}
int32_t set_fcntl(int32_t fd,int32_t flags){
int32_t tmp = fcntl(fd,F_GETFL);
return fcntl(fd,F_SETFL,tmp|flags);
}
int32_t noblock_tcp_socket_server(void){
struct sockaddr_in server_addr,client_addr;
int32_t sin_size,recvbytes;
int32_t sockfd,client_fd;
char buf[BUFFER_SIZE];
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){
perror("socket");
exit(1);
}
config_socket_addr_afinet(&server_addr,PORT,"192.168.246.133");
int32_t en = 1;
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&en,sizeof(en));
if(bind(sockfd,(struct sockaddr*)&server_addr,sizeof(struct sockaddr)) == -1){
perror("bind");
exit(0);
}
if(listen(sockfd,MAX_QUE_CONN_NM) == -1 ){
perror("listen");
exit(1);
}
if(set_fcntl(sockfd,O_NONBLOCK) < 0){
perror("set socket no block error\n");
exit(1);
}
while(1){
sin_size = sizeof(struct sockaddr_in);
do{
if((client_fd = accept(sockfd,(struct sockaddr*)&client_addr,(uint32_t*)&sin_size)) >=0){
printf("connected client: %s\n",inet_ntoa(client_addr.sin_addr));
break;
}
if(errno != EAGAIN){
printf("accept:%s\n", strerror(errno));
}else{
sleep(1);
}
}while(1);
if((recvbytes = recv(client_fd,buf,BUFFER_SIZE,0)) < 0){
perror("recv");
exit(1);
}
printf("recv msg: %s \n",buf);
}
close(client_fd);
exit(1);
}
int32_t tcp_client_tx(const char* argv,const char* buf){
int32_t sockfd,sendbytes;
struct sockaddr_in server_addr;
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){
perror("socket");
exit(1);
}
config_socket_addr_afinet(&server_addr,PORT,argv);
if(connect(sockfd, (struct sockaddr*)&server_addr,sizeof(struct sockaddr)) == -1){
perror("connect");
exit(1);
}
if((sendbytes =send(sockfd,buf,strlen(buf),0)) < 0){
perror("send");
exit(1);
}
close(sockfd);
return 0;
}
int32_t select_tcp_server(void){
struct sockaddr_in server_addr,client_addr;
uint32_t sin_size,count;
fd_set inset,tmp_inset;
int32_t sockfd,client_fd,fd;
char buf[BUFFER_SIZE];
config_socket_addr_afinet(&server_addr,PORT,"192.168.246.133");
if((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1){
perror("socket");
exit(1);
}
int32_t en = 1;
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&en,sizeof(en));
if(bind(sockfd,(struct sockaddr*)&server_addr,sizeof(struct sockaddr)) == -1){
perror("error");
exit(1);
}
if(listen(sockfd,MAX_QUE_CONN_NM) == -1){
perror("listen");
exit(1);
}
printf("listening ... ....\n");
FD_ZERO(&inset);
FD_SET(sockfd,&inset);
while(1){
tmp_inset = inset;
sin_size = sizeof(struct sockaddr_in);
memset(buf,0,strlen(buf));
if(!(select(1024,&tmp_inset,NULL,NULL,NULL)>0)){
perror("select");
}
for(fd = 0 ; fd < 1024 ; fd++){
if(FD_ISSET(fd,&tmp_inset) >0){
if(fd == sockfd){
if((client_fd = accept(sockfd,(struct sockaddr*)&client_addr,&sin_size)) == -1){
perror("accept");
exit(1);
}
FD_SET(client_fd,&inset);
printf("New con from %s\n",inet_ntoa(client_addr.sin_addr));
}else{
if((count = recv(client_fd,buf,BUFFER_SIZE,0))>0){
printf("Msg: %s\n",buf);
}else{
close(fd);
FD_CLR(fd,&inset);
printf("Client fd left: %d \n",fd);
}
}
}
}
}
close(fd);
exit(0);
}
int32_t main(int argc,char* argv[]){
#ifdef MASTER
#ifdef NOBLOCK
noblock_tcp_socket_server();
#else
select_tcp_server();
#endif
#else
tcp_client_tx(argv[1],argv[2]);
#endif
}
根据其他人的代码修改,封装出来的
Makefile
.PHONY:all clean
SERVER=server
SRC=$(wildcard *.c)
OBJS=$(SRC:.c=.o)
CXX=gcc
CLIENT=client
all:
make $(SERVER)
make $(CLIENT)
$(SERVER):
$(CXX) -g -Wall -DMASTER *.c -o $@
$(CLIENT):
$(CXX) -g -Wall *.c -o $@
clean:
rm -rf $(SERVER) $(OBJS) $(CLIENT)
|