上章说完服务器,再来说一下客户端吧;
客户端的任务就轻松多了,由于客户端不需要固定的端口号,因此不必调⽤bind(),客户端的端口号由内核⾃动分配。客户端不是不允许调⽤bind(),只是没有必要调⽤bind()固定⼀个端⼜号,服务器也不是必须调⽤bind(),但如果服务器不调⽤bind(),内核会⾃动给服务器分配监听端⼜,每次启动服务器时端口号都不⼀样,客户端要连接服务器就会遇到⿇烦。
所以客户端只需要操心一个connect()来连接服务器,connect和bind的参数形式⼀致,区别在于bind的参数是⾃⼰的地址,⽽connect的参数是对⽅的地址。connect()成功返回0,出错返回-1。
剩下的跟服务器都是大同小异,所以主要研究服务器就好了;
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <sys/socket.h>
4 #include <netinet/in.h>
5 #include <arpa/inet.h>
6 #include <stdlib.h>
7
8
9 int main(int argc,char* argv[])
10 {
11 if(argc != 3)
12 {
13 printf("tcp_server + ip + port_number\n");
14 exit(1);
15 }
16 int sock = socket(AF_INET,SOCK_STREAM,0);
17 if(sock < 0)
18 {
19 printf("creat socket error\n");
20 exit(2);
21 }
22
23 struct sockaddr_in client_socket;
24 client_socket.sin_family = AF_INET;
25 client_socket.sin_addr.s_addr = inet_addr(argv[1]);
26 client_socket.sin_port = htons(atoi(argv[2]));
27
28 if(connect(sock,(struct sockaddr*)&client_socket,sizeof(client_socket)) < 0)
29 {
30 printf("connect error!\n");
31 return(3);
32 }
33
34 while(1)
35 {
36 char buf[1024];
37 printf("please enter:");
38 fflush(stdout);
39 ssize_t s = read(0,buf,sizeof(buf)-1);
40 if(s > 0)
41 {
42 buf[s] = 0;
43 write(sock,buf,sizeof(buf)-1);
44
45 ssize_t s1 = read(sock,buf,sizeof(buf)-1);
46 if(s1 > 0)
47 {
48 printf("server saying:%s\n",buf);
49 }
50 }
51 }
52
53 return 0;
54 }