接上篇博文,本文是服务器端的实现,主要实现的功能,就是现实客户端的连接,转发客户端发送的消息,以及客户端掉线提示等功能,同时可以在这这上面扩展和TCP以及线程相关的功能木块。
tcpreceive.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#ifndef TCPRECEIVE_H
#define TCPRECEIVE_H
#define BUFFSIZE 2048
#define listen_max 5
int
cond
;
int
rscond
;
typedef
struct
TCP_rcv_arg
{
char
*
local_addr
;
int
tcp_port
;
}
TCP_rcv_arg_t
;
void
stop_handler
(
int
signum
);
void
*
tcppackrecv
(
void
*
arg
);
#endif
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
#include "tcpreceive.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <arpa/inet.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <pthread.h>
void
stop_handler
(
int
sinnum
)
{
cond
=
0
;
rscond
=
0
;
}
void
*
tcppackrecv
(
void
*
arg
)
{
int
listen_fd
,
client_id
,
len
=
1
;
struct
sockaddr_in
server_addr
;
struct
sockaddr_in
client_addr
;
int
sin_size
;
fd_set
master
;
fd_set
read_fds
;
int
fdmax
,
i
,
newfd
,
j
;
char
buf
[
BUFFSIZE
+
1
];
TCP_rcv_arg_t
*
rcv_arg
=
(
TCP_rcv_arg_t
*
)
arg
;
sin_size
=
sizeof
(
client_addr
);
if
(
-
1
==
(
listen_fd
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
)))
{
fprintf
(
stderr
,
"Socket Error:%s
\n
"
,
strerror
(
errno
));
pthread_exit
(
NULL
);
}
memset
(
&
server_addr
,
0
,
sizeof
(
server_addr
));
server_addr
.
sin_family
=
AF_INET
;
server_addr
.
sin_addr
.
s_addr
=
htonl
(
INADDR_ANY
);
//server_addr.sin_addr.s_addr = inet_addr((*rcv_arg).local_addr);
server_addr
.
sin_port
=
htons
((
*
rcv_arg
).
tcp_port
);
setsockopt
(
listen_fd
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
len
,
sizeof
(
len
));
if
(
-
1
==
bind
(
listen_fd
,(
struct
sockaddr
*
)
&
server_addr
,
sizeof
(
server_addr
)))
{
fprintf
(
stderr
,
"Bind Error:%s
\n
"
,
strerror
(
errno
));
pthread_exit
(
NULL
);
}
if
(
-
1
==
listen
(
listen_fd
,
listen_max
))
{
fprintf
(
stderr
,
"Listen Error:%s
\n
"
,
strerror
(
errno
));
pthread_exit
(
NULL
);
}
//printf("listen ok!\n");
FD_ZERO
(
&
master
);
FD_ZERO
(
&
read_fds
);
FD_SET
(
listen_fd
,
&
master
);
fdmax
=
listen_fd
;
cond
=
1
;
while
(
cond
)
{
read_fds
=
master
;
if
(
-
1
==
select
(
fdmax
+
1
,
&
read_fds
,
NULL
,
NULL
,
NULL
))
{
fprintf
(
stderr
,
"Server Select Error:%s
\n
"
,
strerror
(
errno
));
pthread_exit
(
NULL
);
}
for
(
i
=
0
;
i
<=
fdmax
;
i
++
)
{
if
(
FD_ISSET
(
i
,
&
read_fds
))
{
if
(
i
==
listen_fd
)
{
if
(
-
1
==
(
newfd
=
accept
(
listen_fd
,(
struct
sockaddr
*
)
&
client_addr
,(
socklen_t
*
)
&
sin_size
)))
{
fprintf
(
stderr
,
"Accept Error:%s
\n
"
,
strerror
(
errno
));
}
else
{
FD_SET
(
newfd
,
&
master
);
if
(
newfd
>
fdmax
)
{
fdmax
=
newfd
;
}
sprintf
(
buf
,
"Your SocketID is:%d."
,
newfd
);
if
(
send
(
newfd
,
buf
,
21
,
0
)
<
0
)
{
printf
(
"Send Error!
\n
"
);
}
printf
(
"there is a new connection in,form %s,SocketID is %d.
\n
"
,
inet_ntoa
(
client_addr
.
sin_addr
),
newfd
);
}
}
else
{
sprintf
(
buf
,
"Form %2d:
\n
"
,
i
);
if
((
len
=
recv
(
i
,
buf
+
9
,
BUFFSIZE
-
10
,
0
))
<=
0
)
{
if
(
0
==
len
)
{
printf
(
"SocketID %d has left!
\n
"
,
i
);
}
else
{
perror
(
"the recv() go end!
\n
"
);
}
close
(
i
);
FD_CLR
(
i
,
&
master
);
}
else
{
len
+=
9
;
buf
[
len
]
=
'\0'
;
printf
(
"%s
\n
"
,
buf
);
for
(
j
=
0
;
j
<=
fdmax
;
j
++
)
{
if
(
FD_ISSET
(
j
,
&
master
)
&&
j
!=
listen_fd
&&
j
!=
i
)
{
if
(
-
1
==
send
(
j
,
buf
,
len
,
0
))
{
perror
(
"Send() error!
\n
"
);
}
}
}
}
}
}
}
}
pthread_exit
(
NULL
);
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include "tcpreceive.h"
#define PORT 8888
#define IP "192.168.1.220"
int
main
()
{
pthread_t
tid
;
pthread_t
id
;
void
*
tret
;
TCP_rcv_arg_t
rcv_arg
;
rcv_arg
.
tcp_port
=
PORT
;
rcv_arg
.
local_addr
=
IP
;
printf
(
"the main process!
\n
"
);
int
i
=
pthread_create
(
&
tid
,
NULL
,(
void
*
)
tcppackrecv
,(
void
*
)
&
rcv_arg
);
if
(
i
!=
0
)
{
printf
(
"Create pthread error!
\n
"
);
pthread_exit
(
NULL
);
}
if
(
0
!=
pthread_join
(
tid
,
&
tret
))
{
printf
(
"Join pthread error!
\n
"
);
}
return
0
;
}
|
1 2 3 4 5 6 7 8 9 10 |
all:
gcc -c tcpsed.c
ar cr libtcpsed.a tcpsed.o
gcc -c tcpreceive.c
ar cr libtcpreceive.a tcpreceive.o
gcc -o server server.c -L. -ltcpreceive -lpthread
gcc -o client client.c -L. -ltcpsed -lpthread
clean:
rm -rf *.o *.a server client
|
CSDN上面源码下载地址: