linux平台中socket通信程序的编写

文档目的

博主在搭建好的地面与空间通信的模拟通信网络中,A<--->GW1<--->GW2<--->B之间能够顺利ping通,现在要测试是否能建立TCP连接,开始想直接在B上安装apache服务器,然后A上的浏览器输入B的ip地址可以访问B并下载文件,效果如下:

linux平台中socket通信程序的编写_第1张图片

但这样在应用层上是HTTP传输,而且由于对apache内部机制不了解,无法分析传输时的网络层和传输层情况。因此,博主还是倾向于自己用C语言写一个socket通信程序,测试A到B之间的TCP连接和UDP连接,程序设计和实现步骤如下。

环境参数

服务器主机:linux内核版本3.11.0,ubuntu 13.10 amd64

客户端主机:ubuntu 10.04 i386

网关:linux内核版本2.6.27,ubuntu 8.10(这个是转换网关,应用层网关软件要求内核版本是2.6.27,但不运行网关软件的话对于socket通信没有影响)

预备知识

C语言基本语法,socket网络编程基础知识(可以参考点击打开链接 前三章的内容,讲得非常详细),TCP/IP模型

程序设计

一般而言,socket通信过程需要服务器端和客户端都运行一个程序,各自需要以下函数:

就是说在服务器端写一个server.c,包含server一方的socket函数;客户端写一个client.c,包含client一方的socket函数。两边运行实现互通。

但也可以只写一个server.c并在服务器端编译运行,然后在客户端直接利用telnet命令(包括服务器端的ip和端口号)访问服务器端即可完成socket通信。telnet是应用层协议的一种,相对http简单很多,telnet传输应用在socket通信里其实充当了client一方的socket程序的作用,这样几乎减小了一般的工作量。

实现过程

首先,server端编写server.c代码,下面贴上博主自己写的server.c代码:

#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h> 

main(int argc,char *argv[])
{
 //socket()
 int sockfd;
 sockfd=socket(AF_INET,SOCK_STREAM,0);
 if(sockfd==-1)
 {
  perror("create socket failed\r\n");
  return -1;
 }
 
 //bind()
 struct sockaddr_in my_addr; 
 my_addr.sin_family=AF_INET;
 my_addr.sin_port=htons(8000);
 my_addr.sin_addr.s_addr=inet_addr(argv[1]);
 bzero(&(my_addr.sin_zero),20);/*zero the rest of the struct*/
 if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))==-1)
 {
  printf("bind sockfd to my_addr error!\r\n");
  exit(1);
 }

 //listen()
 if(listen(sockfd,10)==-1)
 {
  printf("listen error!\r\n");
  exit(1);
 }

 struct sockaddr_in dest_addr;
 int sin_size;
 int new_sockfd;
 while(1)
 {
  //accept()
  sin_size=sizeof(struct sockaddr_in);
  new_sockfd=accept(sockfd,(struct sockaddr *)&dest_addr,&sin_size);
  if(new_sockfd==-1)
  {
   printf("accept error!\r\n");
   continue;
  }
  printf("server:got connection from:%s\n",argv[2]);
  printf("enter the message\n");
  if(!fork());
  {
   //send()
   char msg[100];
   scanf("%s",msg);
   int len,bytes_sent;
   len=strlen(msg);
   bytes_sent=send(new_sockfd,msg,len,0);
   if(bytes_sent==-1)
    printf("send bytes error!\r\n");
   close(new_sockfd);
   exit(0);
  }/*end if(!fork())*/
  
  //close()
  close(new_sockfd);
 while(waidpid(-1,NULL,0)>0);
 }/*end while*/

}

 然后,在终端利用gcc编译,命令为#gcc -c server.c -o server 
 

编译通过后生成server可执行程序,如果运行提示没有权限就用chmod命令添加执行权限,运行server命令为:

#./server my_ip dest_ip

比如本地ip设为10.210.0.2,目的ip是192.168.1.2,则输入命令:

#./server 10.210.0.2 192.168.1.2

运行完后终端处于阻塞状态,即处于accept()。此时在客户端的终端上键入telnet命令,以我设置的服务器ip和程序中设置的端口号为例,命令为:

#telnet 10.210.0.2 8000

现在服务器就可以推送消息给客户端了,在服务器运行一段键入字符串并回车,客户端的终端上就能收到这些字符信息。在程序中的头几行里大家有没有注意到这句

<pre name="code" class="cpp">sockfd=socket(AF_INET,SOCK_STREAM,0);

 SOCK_STREAM代表程序运行后socket以流式套接字的方式通信,也就是TCP连接。如果你想测试UDP连接,那可以把SOCK_STREAM替换为SOCK_DGRAM,这样socket就会以数据报格式通信。 
 

如果你TCP和UDP连接都成功了做到了,恭喜你,你刚刚迈出了成为网络程序员的第一步!

总结

其实只要有一定的网络理论和C语言知识,socket编程并不难,关键要搞懂通信过程,函数的调用是有顺序的,不能随便编写。当然博主的程序存在交互不强,关闭进程偶尔出错,耦合性太强,运行不方便等缺点,但大方向把握对了后期完善就很简单了。最后,祝各位看官也能轻松学到socket编程知识!


你可能感兴趣的:(linux,tcp,socket,C语言,网络编程)