上章說完服務器,再來說一下客戶端吧;
客戶端的任務就輕鬆多了,由於客戶端不需要固定的端口號,因此不必調⽤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 }