《Makefile》
# Makefile
#
#CROSS_COMPILE = arm-linux-gnu-
CC = $(CROSS_COMPILE)gcc
ifdef CROSS_COMPILE
TARGET = /opt/filesystem
endif
DEBUG = -g -O0 -Wall
CFLAGS += $(DEBUG)
PROGS = ${patsubst %.c, %, ${wildcard *.c}}
all : $(PROGS)
install: $(PROGS)
ifdef CROSS_COMPILE
mkdir $(TARGET)/root/long_term/networks -p
cp $(PROGS) $(TARGET)/root/long_term/networks -f
endif
% : %.c
$(CC) $(CFLAGS) $< -o $@
.PHONY: uninstall clean dist
uninstall :
ifdef CROSS_COMPILE
cd $(TARGET)/root/long_term/networks && rm -f $(PROGS)
endif
clean : uninstall
- rm -f $(PROGS) core *.gz *~
dist: clean
tar czf ../farsight_simple_select_demo1.41.tar.gz *.c ../myselect
***************************************************************************
《server》服务端,等待显示信息
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "list.h"
struct cli_list
{
struct list_head list;
int clifd;
};
#define DEF_SERV_PORT 5432
#define DEF_SERV_IP "192.168.1.101"
struct cli_list *head = NULL;
void usage (char *s)
{
printf ("%s [ipaddr] [port]\n", s);
printf ("[ipaddr] --options, your server IP addr,default is %s\n", DEF_SERV_IP);
printf ("[port] --options, your server listening port, default is %d\n\n", DEF_SERV_PORT);
// exit (1);
}
static inline void broadcast_msg (struct cli_list *head, int sockfd, const void *buf, size_t len, int flags)
{
int ret = -1;
struct list_head *p, *n;
struct cli_list *pnode;
list_for_each_safe (p, n, &head->list) {
pnode = list_entry (p, struct cli_list, list);
if (pnode->clifd != -1 && pnode->clifd != sockfd) {
do {
ret = send (pnode->clifd, buf, len, flags);
} while (ret < 0 && EINTR == errno);
if (ret < 0) {
printf ("broadcast failed\n");
}
} else {
continue;
}
}
return;
}
int main (int argc, char *argv[])
{
char buf[BUFSIZ];
int fd, newfd, len;
socklen_t clen = -1;
struct sockaddr_in sin;
struct sockaddr_in cin;
struct cli_list *mylist;
char ip_dot_addr[17];
fd_set rset;
int b_reuse = 1;
head = (struct cli_list *) malloc (sizeof (struct cli_list));
if (!head) {
printf ("malloc failed\n");
exit (1);
}
head->clifd = -1;
INIT_LIST_HEAD (&head->list);
mylist = head;
fd = socket (AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
fprintf (stderr, "ERROR: Can not create socket!\n");
exit (1);
}
setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, &b_reuse, sizeof (int));
usage (argv[0]); //give a guide.
bzero ((char *) &sin, sizeof (sin));
sin.sin_family = AF_INET;
switch (argc) {
case 1:
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons (DEF_SERV_PORT);
break;
case 3:
sin.sin_addr.s_addr = inet_addr (argv[1]);
sin.sin_port = htons (atoi (argv[2]));
break;
case 2:
if (strchr (argv[1], '.') != NULL) { //argv[1] is server ip address
sin.sin_addr.s_addr = inet_addr (argv[1]);
sin.sin_port = htons (DEF_SERV_PORT);
} else { //argv[1] is server port
sin.sin_port = htons (atoi (argv[1]));
sin.sin_addr.s_addr = INADDR_ANY;
}
break;
default:
usage (argv[0]);
exit (1);
break;
}
if (bind (fd, (struct sockaddr *) &sin, sizeof (sin)) < 0) {
fprintf (stderr, "bind error!\n");
exit (1);
}
listen (fd, 10);
strcpy (ip_dot_addr, "any IP");
if (sin.sin_addr.s_addr != INADDR_ANY) {
if (inet_ntop (AF_INET, (void *) &sin.sin_addr, ip_dot_addr, sizeof (ip_dot_addr)) == NULL) {
fprintf (stderr, "inet_ntop error!\n");
exit (1);
}
ip_dot_addr[16] = '\0';
}
printf ("Server bind at %s:%d\n", ip_dot_addr, ntohs (sin.sin_port));
while (1) {
struct cli_list *tmp;
struct list_head *pos, *q;
int maxfd = -1;
/*1. 把fd,所有的已经建立好连接的socket描述符加入到rset */
FD_ZERO (&rset);
FD_SET (fd, &rset);
maxfd = fd;
list_for_each_safe (pos, q, &mylist->list) {
tmp = list_entry (pos, struct cli_list, list);
FD_SET (tmp->clifd, &rset);
if (tmp->clifd > maxfd)
maxfd = tmp->clifd;
}
/*2. 调用select() */
select (maxfd + 1, &rset, NULL, NULL, NULL);
/*3.查看那个文件描述符有数据 */
if (FD_ISSET (fd, &rset) > 0) {
/* 有新的客户端连接请求 */
do {
clen = sizeof (cin);
newfd = accept (fd, (struct sockaddr *) &cin, &clen);
} while (newfd < 0 && errno == EINTR);
if (newfd < 0) {
fprintf (stderr, "Err: Can't accept socket!\n");
exit (1);
}
if (inet_ntop (AF_INET, (void *) &cin.sin_addr.s_addr, ip_dot_addr, sizeof (ip_dot_addr)) == NULL) {
fprintf (stderr, "inet_ntop error!\n");
exit (1);
}
ip_dot_addr[16] = '\0';
printf ("Client %s:%d connected!\n", ip_dot_addr, ntohs (cin.sin_port));
tmp = (struct cli_list *) malloc (sizeof (struct cli_list));
if (tmp == NULL) {
fprintf (stderr, "malloc error\n");
exit (1);
}
tmp->clifd = newfd;
list_add (&(tmp->list), &(mylist->list));
}
list_for_each_safe (pos, q, &mylist->list) {
tmp = list_entry (pos, struct cli_list, list);
if (FD_ISSET (tmp->clifd, &rset)) { /* 已建立的连接有数据可读 */
int need_free_flags = 0;
bzero (buf, BUFSIZ);
do {
len = read (tmp->clifd, buf, BUFSIZ);
} while (len < 0 && EINTR == errno);
buf[BUFSIZ -1] = '0';
if (strncmp (buf, "quit", 4) == 0) {
bzero(buf,BUFSIZ);
sprintf(buf,"%s%d exited.\n", "fd=",tmp->clifd);
need_free_flags = 1;
}
/* output the string */
fprintf (stderr, "%s", buf);
/* broadcasting */
broadcast_msg (head, tmp->clifd, buf, strlen (buf), 0);
if (need_free_flags) {
close (tmp->clifd);
list_del ((struct list_head *) tmp);
free(tmp);
tmp = NULL;
}
}
}
}
close (fd);
return 0;
}
执行:
lsb@ubuntu:~/gx/wangluo$ ./select_tcp_server 192.168.1.101
./select_tcp_server [ipaddr] [port]
[ipaddr] --options, your server IP addr,default is 192.168.1.101
[port] --options, your server listening port, default is 5432
Server bind at 192.168.1.101:5432
等客户端起来后:
Client 192.168.1.101:52166 connected!
表示连接成功:
信息:(客户端发过来的信息)
kai shi lian jie
OK
*************************************************************
《client》客户端---即发信息端
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#define DEF_SERV_PORT 5432
#define DEF_SERV_IP "192.168.1.101"
void usage (char *s)
{
printf ("%s [ipaddr] [port]\n", s);
printf ("[ipaddr] --options, your server IP addr,default is %s\n", DEF_SERV_IP);
printf ("[port] --options, your server listening port, default is %d\n", DEF_SERV_PORT);
exit (1);
}
int main (int argc, char *argv[])
{
char buf[BUFSIZ], *p;
struct sockaddr_in sin;
int fd, len;
fd_set rset;
fd = socket (AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
fprintf (stderr, "ERROR: Can not create socket!\n");
exit (1);
}
bzero ((char *) &sin, sizeof (sin));
sin.sin_family = AF_INET;
switch (argc) {
case 1:
sin.sin_addr.s_addr = inet_addr (DEF_SERV_IP);
sin.sin_port = htons (DEF_SERV_PORT);
break;
case 3:
sin.sin_addr.s_addr = inet_addr (argv[1]);
sin.sin_port = htons (atoi (argv[2]));
break;
case 2:
if (strchr (argv[1], '.') != NULL) { //argv[1] is server ip address
sin.sin_addr.s_addr = inet_addr (argv[1]);
sin.sin_port = htons (DEF_SERV_PORT);
} else { //argv[1] is server port
sin.sin_port = htons (atoi (argv[1]));
sin.sin_addr.s_addr = inet_addr (DEF_SERV_IP);
}
break;
default:
usage (argv[0]);
break;
}
if (connect (fd, (struct sockaddr *) &sin, sizeof (sin)) < 0) {
fprintf (stderr, "connect error!\n");
exit (1);
}
while (1) {
int maxfd = -1;
struct timeval delay = { 5, 0 };
FD_ZERO (&rset);
FD_SET (0, &rset);
FD_SET (fd, &rset);
maxfd = fd;
/*2. 调用select() */
select (maxfd + 1, &rset, NULL, NULL, &delay);
/*3.查看那个文件描述符有数据 */
if (FD_ISSET (fd, &rset) > 0) { /* 套接字有数据 */
bzero (buf, BUFSIZ);
do {
len = read (fd, buf, BUFSIZ);
} while (len < 0 && EINTR == errno);
if (len > 0) {
p = buf;
while (len-- > 0)
fprintf (stderr, "%c", *p++);
}
}
if (FD_ISSET (0, &rset) > 0) { /* 标准输入终端有数据 */
bzero (buf, BUFSIZ);
do {
len = read (0, buf, BUFSIZ);
} while (len < 0 && EINTR == errno);
if (len > 0) {
send (fd, buf, len, 0);
}
if (strncmp (buf, "quit", 4) == 0) {
sleep(1);
break;
}
}
}
close (fd);
return 0;
}
执行:
lsb@ubuntu:~/gx/wangluo$ ./select_tcp_client 192.168.1.101
kai shi lian jie
OK
********************************************************************************
若先执行客户端的话,就会
connect error!
所以,一上来就连接客户端