TCP协议

本文详细介绍了如何用C语言通过TCP协议实现一个服务器端程序,包括创建套接字、设置复用选项、绑定和监听端口、接受客户端连接以及数据收发过程。同时,还展示了客户端如何连接到服务器并进行交互。
摘要由CSDN通过智能技术生成
TCP服务器
 1 #include <stdio.h>
 2 #include <sys/types.h>
 3 #include <sys/socket.h>
 4 #include <arpa/inet.h>
 5 #include <netinet/in.h>
 6 #include <string.h>
 7 #include <unistd.h>
 8 
 9 #define PORT 8888 //1024-49151
10 #define IP "192.168.124.105"
11 
12 int main(int argc, const char *argv[])
13 {
14     //创建流式套接字文件
15     int sfd =socket(AF_INET,SOCK_STREAM,0);
16     if(sfd<0)
17     {
18         fprintf(stderr,"line:%d ",__LINE__);
19         perror("socket");
20         return -1;
21     }
22     printf("创建流式套接字成功 sfd=%d __%d__\n",sfd,__LINE__);
23     //允许端口号被快速重复使用
24     int reuse = 1;
25     if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
26     {
27         fprintf(stderr, "line:%d  ", __LINE__);
28         perror("setsockopt");
29         return -1;
30 
31     }
32                                                                               
33     //填充服务器的地址信息结构体,真实的地址信息结构体根据地址族制定
34     //AF_INET ---->man 7 ip 
35     struct sockaddr_in sin;
36     sin.sin_family   =AF_INET;//必须填AF_INET;
37     sin.sin_port     =htons(PORT);//端口号的网络字节序 1024-49151
38     sin.sin_addr.s_addr=inet_addr(IP);//ifconfig查看本机的IP地址
39     //绑定服务器自身的地址信息---》必须绑定
40     if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin))<0)
41     {
42         fprintf(stderr,"lin:%d  ",__LINE__);
43         perror("bind");
44         return -1;
45     }
46     printf("bind success __%d__\n",__LINE__);
47     //将套接字设置为被动监听状态
48     if(listen(sfd,128)<0)
49     {
50         fprintf(stderr,"line:%d  ",__LINE__);
51         perror("listen");
52         return -1;
53     }
54     printf("listen success __%d__\n",__LINE__);
55 
56     struct sockaddr_in cin;//存储客户端信息的
57     socklen_t addrlen =sizeof(cin);
58     //会从已完成连接队列的对头获取一个客户端的信息,生成一个新的文件描述符
59     //accept(sfd,NULL,NULL)
60     int newfd=accept(sfd,(struct sockaddr*)&cin,&addrlen);
61     if(newfd<0)
62     {
63         fprintf(stderr,"line:%d  ",__LINE__);
64         perror("accept");
65         return -1;
66     }
67     printf("[%s:%d]客户端连接成功  newfd=%d __%d__\n",\
68             inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd,__LINE__);
69 
70     char buf[128];
71     ssize_t res;
72     while(1)
73     {
74         bzero(buf,sizeof(buf));
75         //接收                                                                            
76         res=recv(newfd,buf,sizeof(buf),0);
77         if(res<0)
78         {
79             fprintf(stderr,"line:%d  ",__LINE__);
80             perror("recv");
81             return -1;
82         }
83         else if(0==res)
84         {
85             printf("[%s:%d]客户端下线 newfd=%d  __%d__\n",\
86                     inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd,__LINE__);
87             break;
88         }
89         printf("[%s:%d] 客户端连接成功 newfd=%d %s_%d__\n",\
90                 inet_ntoa(cin.sin_addr),ntohs(cin.sin_port),newfd,buf,__LINE__);
91         //发送
92         strcat(buf,"*_*");
93         if(send(newfd,buf,sizeof(buf),0)<0)
94         {
95             fprintf(stderr,"line:%d  ",__LINE__);
96             perror("send");
97             return -1;
98         }
99         printf("send success __%d__\n",__LINE__);
100                                                        
101         }
102     //关闭文件描述符
103     close(newfd);
104     close(sfd);
105 
106     return 0;
107 }
TCP客服端
 1 #include <stdio.h>
 2 #include <sys/types.h>
 3 #include <sys/socket.h>
 4 #include <arpa/inet.h>
 5 #include <netinet/in.h>
 6 #include <string.h>
 7 #include <unistd.h>
 8 #include <stdlib.h>
 9 
10 #define CLI_PORT 7777 //1024-49151
11 #define CLI_IP "192.168.124.105"
12 
13 int main(int argc, const char *argv[])
14 {
15     if(argc <3)
16     {
17         printf("请在命令行传入服务器的port和 ip\n");
18         return -1;
19     }
20 
21     //创建流式套接字文件
22     int cfd =socket(AF_INET,SOCK_STREAM,0);
23     if(cfd<0)                                                                    
24     {
25         fprintf(stderr,"line:%d ",__LINE__);
26         perror("socket");
27         return -1;
28     }
29     printf("创建流式套接字成功, cfd=%d __%d__\n",cfd,__LINE__);
30     //允许端口号被快速重复使用
31     int reuse = 1;
32     if(setsockopt(cfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0)
33     {
34         fprintf(stderr, "line:%d  ", __LINE__);
35         perror("setsockopt");
36         return -1;
37 
38     }
39                                                                                                         
40     //填充客户端的地址信息,给bind函数绑定使用
41     //真实的地址信息结构体根据地址族制定 AF_INET-->》man 7 IP
42     struct sockaddr_in cin;
43     cin.sin_family   =AF_INET;//必须填AF_INET;
44     cin.sin_port     =htons(CLI_PORT);//客户端要绑定的端口号
45     cin.sin_addr.s_addr=inet_addr(CLI_IP);//客户端绑定的IP地址
46     //填充服务器的地址信息,给connect函数使用
47     struct sockaddr_in sin;
48     sin.sin_family   =AF_INET;//必须填AF_INET;
49     sin.sin_port     =htons(atoi(argv[1]));//服务器绑定的端口号
50     sin.sin_addr.s_addr=inet_addr(argv[2]);//服务器要运行的主机的IP的网络地址
51     if(connect(cfd,(struct sockaddr*)&sin,sizeof(sin))<0)
52     {
53         fprintf(stderr,"line:%d  ",__LINE__);
54         perror("accept");
55         return -1;
56     }
57     printf("connect server[%s:%s] success __%d__\n",argv[2],argv[1],__LINE__);
58 
59     char buf[128]="";
60     ssize_t res;
61     while(1)
62     {
63         printf("请输入数据>>>");
64         fgets(buf,sizeof(buf),stdin);
65         buf[strlen(buf)-1]='\0';
66         //发送
67         if(send(cfd,buf,sizeof(buf),0)<0)
68         {
69             fprintf(stderr,"line:%d  ",__LINE__);
70             perror("send");                                  
71             return -1;
72         }
73         printf("发送成功 __%d__\n",__LINE__);
74 
75         //接收
76         bzero(buf,sizeof(buf));
77         res=recv(cfd,buf,sizeof(buf),0);
78         if(res<0)
79         {
80             fprintf(stderr,"line:%d  ",__LINE__);
81             perror("recv");
82             return -1;
83         }
84         else if(0==res)
85         {
86             printf("服务器下线  __%d__\n",__LINE__);
87             break;
88         }
89         printf(":%s __%d__\n",buf,__LINE__);
90 
91     }
92     //关闭文件描述符
93 
94     close(cfd);
95 
96     return 0;
97 }
98 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值