/
server注释(new)
131 lines (129 loc) · 4.05 KB
/
server注释(new)
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
#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<unistd.h>
#include<arpa/inet.h>
#include<pthread.h>
#define max_num 1960
#define max 6
#define SERV_PORT 6666
char mess[2222];
int a[max]={0};(主要用来存储客户端的socket连接套接字)
int conn_fd;
int SendToClient(int se,char* buf,int Num) {
int i;
for(i=0;i<max;i++){
printf("a[%d]=%d\n",i,a[i]);
if((a[i]!=0)&&(a[i]!=se)){send(a[i],buf,Num,0);
printf("send information to %d\n",a[i]);
}
}
return 0;
}
void *pthread_ser(void* ser) {
int se=*(int *)ser;
while(1)
{
int num,i;
num=recv(se,mess,max_num,0);
if(num<=0){
for(i=0;i<max;i++){
if(se==a[i]){
a[i]=0;
}
}
printf("num=%d\n",num);
printf("end! se=%d\n",se);
break;
}
printf("recv information from %d,big=%d\n",se,num);
SendToClient(se,mess,num);
bzero(mess,max_num);
}
close(se);
}
int send_info() {(该函数的功能主要是收到客户端的信息后,给客户端答复)
stpcpy(mess,"I have rcv your messages--from server!\n");
if (send(conn_fd, mess, strlen(mess), 0) == -1)
{
printf("--failed to send this message!\n");
return 0;
}
return 1;
}
int main(){
int number=0;
int se;
int socket_fd=socket(AF_INET, SOCK_STREAM, 0);//创建一个监听socket
int listen_fd=socket(AF_INET, SOCK_STREAM, 0);//创建一个监听socket
char buff[max_num];
char ipAddr[INET_ADDRSTRLEN];//该参数在<netinet/in.h>中,意即数组的最大长度
if( socket_fd==-1 ){
printf("create socket error: %s(errno: %d)\n",strerror(errno),errno);
return 0;
}//创建监听失败
struct sockaddr_in servaddr,peerAddr,cliaddr;
int peerLen;
int size;
size=sizeof(struct sockaddr_in);
//memset(&servaddr, 0, sizeof(servaddr));
int l=SO_REUSEADDR;//SO_REUSEADDR用于对TCP套接字处于TIME_WAIT状态下的socket,才可以重复绑定使用
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &l,sizeof(l));//用于套接口的设置选项值。
bzero(&servaddr,sizeof(servaddr)); //将字节字符串的字节置0
servaddr.sin_family = AF_INET;//选择网络协议
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//指本机,这里为0.0.0.0
servaddr.sin_port = htons(SERV_PORT);(确定端口,这里为6666)
if( bind(listen_fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){//绑定端口地址
perror("bind error");
exit(1);
}
if( listen(listen_fd, 10) == -1){开始监听
printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno);
return 0;
}
printf("waiting for client's request\n");
int n;
int m;
while(1){//循环接受客户端的消息
if( (conn_fd = accept(listen_fd, (struct sockaddr*)NULL, NULL)) == -1){接受客户端发来的套接字
printf("accept socket error: %s(errno: %d)",strerror(errno),errno);
continue;
}
while(1){
peerLen=sizeof(peerAddr);
if(getpeername(conn_fd, (struct sockaddr *)&peerAddr, &peerLen) == -1){//获取端口名
printf("getpeername error\n");
exit(0);
}
printf("connected peer address = %s:%d\n",inet_ntop(AF_INET,&peerAddr.sin_addr, ipAddr, sizeof(ipAddr)), ntohs(peerAddr.sin_port));//获取客户端的IP地址(peerAddr)
if(number>=max){//用来记录客户端的个数
printf("no more client is allowed\n");
close(se);
}
int i;
for(i=0;i<max;i++){
if(a[i]==0){
a[i]=se;(循环接受套接字)
break;
}
}
pthread_t tid;
pthread_create(&tid,NULL,(void*)pthread_ser,&se);//多线程参数传递
number+=1;
n = recv(conn_fd, buff, max, 0);//从TCP连接的另一端接受数据
buff[n] = '\0';
if(n!=0){
printf("recv msg from client: %s\n", buff);
send_info();}//给客户端返回数据
else {
break;}
}
close(conn_fd);
}
close(listen_fd);
return 0;
}