linux C语言tcpserver端口数据转发
为方便四信lora接收设备的TCPSERVER模式的数据传输,写的本机端口数据转发,具体流程如下:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: main.c
* Author: b
*
* Created on 2018年4月13日, 下午3:01
*/
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<pthread.h>
#include <malloc.h>
#include<errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include<string.h>
#define BACKLOG 1
#define MAXRECVLEN 1024
#define LISTENPORT 5008
#define FORWORDPORT 5011
#define XORN 3
/*
*
*/
int max(int a, int b) {
return a > b ? a : b;
}
int main(int argc, void **argv) {
unsigned char buf[MAXRECVLEN];
int mymap[1024], connectfd[1024];
int server_sockfd1, server_sockfd2, client_sockfd;
int server_len, client_len;
struct sockaddr_in server_address1, server_address2, client_address;
int maxfdid, result;
int opt = SO_REUSEADDR;
fd_set readfds, testfds;
int flag = 0;
memset(mymap, -1, sizeof (mymap));
memset(connectfd, -1, sizeof (connectfd));
client_len = sizeof (struct sockaddr_in);
/*设置端口1的监听*/
server_sockfd1 = socket(AF_INET, SOCK_STREAM, 0); //建立服务器端socket
// setsockopt(server_sockfd1, SOL_SOCKET, SO_REUSEADDR, (const void *) &opt, (socklen_t)sizeof (opt));
server_address1.sin_family = AF_INET;
server_address1.sin_port = htons(LISTENPORT);
server_address1.sin_addr.s_addr = htonl(INADDR_ANY);
server_len = sizeof (server_address1);
bind(server_sockfd1, (struct sockaddr *) &server_address1, server_len);
listen(server_sockfd1, 2);
/**设置端口二的监听*/
server_sockfd2 = socket(AF_INET, SOCK_STREAM, 0); //建立服务器端socket
// setsockopt(server_sockfd2, SOL_SOCKET, SO_REUSEADDR, (const void *) &opt, (socklen_t)sizeof (opt));
server_address2.sin_family = AF_INET;
server_address2.sin_port = htons(FORWORDPORT);
server_address2.sin_addr.s_addr = htonl(INADDR_ANY);
bind(server_sockfd2, (struct sockaddr *) &server_address2, server_len);
listen(server_sockfd2, 2);
FD_ZERO(&readfds);
FD_SET(server_sockfd1, &readfds);
FD_SET(server_sockfd2, &readfds);
// printf("%d %d\n", server_sockfd1, server_sockfd2);
maxfdid = max(server_sockfd1, server_sockfd2);
while (1) {
int fdid, readnum;
testfds = readfds;
result = select(maxfdid + 1, &testfds, (fd_set *) 0, (fd_set *) 0, (struct timeval *) 0); //阻塞,知道有一个返回1为止
if (result < 1) {
perror("SERVER ERROR");
exit(1);
}
for (fdid = 0; fdid <= maxfdid; fdid++) {
if (FD_ISSET(fdid, &testfds)) {
if (fdid == server_sockfd1 || fdid == server_sockfd2) {
client_sockfd = accept(fdid, (struct sockaddr *) &client_address, &client_len);
if (fdid == server_sockfd1)
connectfd[client_sockfd] = 1;
else
connectfd[client_sockfd] = 2;
FD_SET(client_sockfd, &readfds); //将客户端socket加入到集合中
maxfdid = max(maxfdid, client_sockfd);
time_t nowtime = time(NULL);
char *chartime = ctime(&nowtime);
printf("You got a connection from client's ip %s, port %d at time %s\n", inet_ntoa(client_address.sin_addr), htons(client_address.sin_port), chartime);
} else {
char n;
ioctl(fdid, FIONREAD, &n); //取得数据量交给nread 获取有多少数据
/*客户数据请求完毕,关闭套接字,从集合中清除相应描述符 */
if (n == 0) {
close(fdid);
connectfd[fdid] =-1;
FD_CLR(fdid, &readfds);
printf("removing client on fd %d\n", fdid);
}/*处理客户数据请求*/
else {
int readn = read(fdid, &buf, n);
// printf("read num:%d", (int) readn);
// for (int i = 0; i < readn; i++) {
// printf("%02x ", buf[i]);
// }
// printf("\n serving client on fd %d\n", fdid);
flag = connectfd[fdid]^3;
for (int beg = 0; beg <= maxfdid; beg++)
if (connectfd[beg] == flag){
write(beg, buf, n);
// printf("write:_________\n");
}
}
}
}
}
}
}