日期:2014-05-16 浏览次数:20661 次
Ubuntu的终端用来搞c和c++真是太方便了,哪像windows下的turboC那么麻烦啊!
?
直接vi编辑一个.c 或 .cpp 文件,然后g++ 或 gcc 一编译,直接? ./a.out运行,真是太方便了。
?
不熟悉的函数直接man一下就ok了。好东西啊!
?
?
现在就用这东西学习一下socket吧:
?
1.首先搞一个服务端:
?
vi a.c
?
内容如下:
?
#include <stdio.h> #include <string.h> #include <stdlib.h> // 引入的三个头文件,是必需的: #include <netinet/in.h> #include <sys/socket.h> #include <arpa/inet.h> // 两个结构体,下面要用的,实例化了?NO,没有实例化 // 只是重命名了,为什么要这样呢? typedef struct sockaddr_in SOCKADDR_IN; typedef struct sockaddr SOCKADDR ; // 入口main,注意参数,这个是要输入的启动参数, // 例如:./service 9999,其中9999就是输入的参数 // 是个char数组,可以传入多个参数,按顺序 int main(int argc,char **argv) { // 1.创建套接字 // 参数:SOCK_DGRAM是基于UDP的socket通信模式, // 如果是TCP的话是SOCK_STREAM. int fd = socket(AF_INET, SOCK_DGRAM, 0); // 声明一个服务端和一个客户端的结构体对象: SOCKADDR_IN addrSrv ; SOCKADDR_IN addrClient; // 定义接收和发送的字符串 char recvBuf[100] = {0}; char sendBuf[100] = {0}; // 服务端的长度,下面要用到 int len = sizeof(addrSrv); // 服务端的地址, // INADDR_ANY 可接受的客户端是任意地址 addrSrv.sin_addr.s_addr = htonl(INADDR_ANY); addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(atoi(argv[1]));// 服务端的端口号 // 绑定套接字和端口 bind(fd,(struct sockaddr *)&addrSrv,sizeof(addrSrv)); while(1){ // 接收客户端信息 recvfrom(fd, recvBuf, 16, 0, (SOCKADDR*)&addrClient, &len); printf("recvBuf :%s\n",recvBuf); printf("please input data:\n"); fgets(sendBuf,100,stdin); // 发送给客户端信息 sendto(fd,sendBuf,20,0,(SOCKADDR*)&addrClient, len); } // 关闭套接字 close(fd); // 可以有或没有return 1; }?
?
2.构建一个客户端:
?
vi b.c
?
代码如下:
?
#include <stdio.h> #include <string.h> #include <stdlib.h> // 引入的三个头文件,是必需的: #include <netinet/in.h> #include <sys/socket.h> #include <arpa/inet.h> typedef struct sockaddr_in SOCKADDR_IN; typedef struct sockaddr SOCKADDR ; int main(int argc,char **argv) { int fd = socket(AF_INET, SOCK_DGRAM, 0); SOCKADDR_IN addrSrv ; SOCKADDR_IN addrClient; char recvBuf[100] = {0}; char sendBuf[100] = {0}; int len = sizeof(addrClient); // 此处的输入的第二个参数是指定服务端的ip地址 addrSrv.sin_addr.s_addr = inet_addr(argv[2]); addrSrv.sin_family = AF_INET; // 输入的第一个参数,服务端的端口号 addrSrv.sin_port = htons(atoi(argv[1])); // 跟服务端的不同之处,不用绑定套接字和端口 // bind(fd,(struct sockaddr *)&addrSrv,sizeof(addrSrv)); while(1) { printf("please inpur data\n"); fgets(sendBuf,100,stdin); sendto(fd,sendBuf,20,0,(SOCKADDR*)&addrSrv, len); recvfrom(fd, recvBuf, 16, 0, (SOCKADDR*)&addrClient, &len); printf("recvBuf %s\n",recvBuf); } close(fd); return 0; }?
两者差别不多,只两点:1.客户端需要指定服务端的ip和端口,所以执行的时候需要输入端口和ip。
?
??????????????????????????????????????????? 2.客户端不需要绑定端口。
?
?
3.编译:
?
gcc a.c -o server
?
?
gcc b.c -o client
?
?
4.运行:
?
./server 9999
?
从另一个终端运行:
?
./client? 9999 192.168.*.*
?
?
5.结果,不同的终端代表不同的进程,通过输入和打印出的信息就能证明两者开始交互了。
?
?
?
?