TCP_IP第三次作业


由于自己的偷懒,现在才开始补作业。
2017年1月9日22点

#第三次 写一个具有服务器以及客户端的程序(远程控制)

#服务器端设计

bind函数

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
int Bind(const char* ip, int port) {
//创建tcp套接字
int serv_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

//允许创建端口号相同但IP地址不同的多个socket描述符
int opt = 1;
setsockopt(serv_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

//将套接字和IP、端口绑定
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr)); //每个字节都用0填充
serv_addr.sin_family = AF_INET; //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr(ip); //具体的IP地址
serv_addr.sin_port = htons(port); //端口
if(-1 == bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))) {
std::string str("Error bind on");
char s[6];
sprintf(s, "%d", port);
str = str+ip+":"+s;
perror(str.c_str());
return -1;
} else {
printf("成功绑定端口%s:%d\n", ip, port);
}

return serv_sock;
}

开启服务器,监听客户端请求

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
void server_run(const char* ip, int port) {
int serv_sock = Bind(ip, port);
if(serv_sock == -1) {
return;
}

//进入监听状态,等待用户发起请求
listen(serv_sock, 20);

//接收客户端请求
sockaddr_in clnt_addr;
socklen_t clnt_addr_size = sizeof(clnt_addr);

char str[] = "Hello World!";
char strip[32];
char buffer[40];

int clnt_sock;


while((clnt_sock = accept(serv_sock, (sockaddr*)&clnt_addr, &clnt_addr_size)) >= 0) {
// 向客户端发送数据
write(clnt_sock, str, sizeof(str));

//进行处理,这边不具体写了!可以多线程,也可以单线程,这里不写了!
}


//关闭套接字
close(serv_sock);
}

##开启服务端
开启方式,按照下面的,就可以开启了,不过服务器端的业务逻辑没写,所以程序是跑不了的

1
2
3
const char *ip = "127.0.0.1";
int port = 12344;
server_run(ip, port);

#客户端设计
客户端只需要创建套接字,与服务器相连,反而容易设计:

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
void client_run_cmd(const char* ip, int port) {
//创建套接字
int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

//向服务器(特定的IP和端口)发起请求
struct sockaddr_in serv_addr;
memset(&serv_addr, 0, sizeof(serv_addr)); //每个字节都用0填充
serv_addr.sin_family = AF_INET; //使用IPv4地址
serv_addr.sin_addr.s_addr = inet_addr(ip); //具体的IP地址
serv_addr.sin_port = htons(port); //端口
if(-1 == connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr))) {
std::string str("Error connect on");
char s[6];
sprintf(s, "%d", port);
str = str+ip+":"+s;
perror(str.c_str());
return;
} else {
printf("Success connected on %s:%d\n", ip, port);
}

char buffer[1024];
int bufsize = 1024;
int maxfd = sock, rRes, wRes, r1Res;
fd_set sockSet, inSet, rSet, wSet, r1Set;
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 1000;

FD_ZERO(&sockSet);
FD_ZERO(&inSet);
FD_SET(sock, &sockSet);
FD_SET(STDIN_FILENO, &inSet);

bool cmdflag = false, receiveing = false;
char* cmdbuf[20];
int cmdbuflen;
// int memflen = 1024*1024*4;
// char memfile[memflen];
FILE * pfile;
char rfilename[50];
char wBuffer[1024];
while(1) {
//业务逻辑处理,不写了
}
}