linux下C/C++学习 & socket

1、c的一个例子
(1)文本文件HelloWorld.c
#include <stdio.h>
void main()
{
    printf("Hello World!\n");
}
(2)
不生成HelloWorld.o,直接生成HelloWorld.exe
gcc -o  HelloWorld.exe HelloWorld.c
 
生成HelloWorld.o,再生成HelloWorld.exe
gcc –c HelloWorld.o HelloWorld.c
gcc –o HelloWorld.exe HwlloWorld.c
 
默认生成可执行文件a.out
gcc HelloWorld.c
(3)执行
./HelloWorld.exe
 
注:也可用gcc HelloWorld.c编译!
 
 
 
2、C++的一个例子
(1)文本文件helloworld.cpp输入下列内容
#include <iostream>
using namespace std;
int main()
{
    cout<&lt;"Hello World!"&lt;&lt;endl;   
    return 0;
}
(2) g++ –o helloworld.exe helloworld.cpp
(3)./helloworld.exe
注意:
(1)头文件为iostream而不是老版本的iostream.h
(2)指明命名空间,不然会出错。
(3)main 返回 int型,void型会出错。
(4)编译用g++而不是gcc
(5)后缀名为cpp,其它后缀名可能会出错。
 
补充:c、c++混合

#include &lt;stdio.h>
#include <iostream>
using namespace std;

int main()
{
    printf("Hello World in c language!\n");
    cout<&lt;"Hello World in c++ language!"&lt;&lt;endl;
}

用g++编译正确!

3、C++调用shell     c调用shell头文件为#include &lt;stdlib.h>
(1)hellosh.cpp文本文件输入以下内容
#include<iostream>  
#include <cstdlib>
using namespace std;
int main()
{   
    for(int i=0;i<2;i++)
    {
        system("ifconfig");   
    }
    return 0;
}
(2)g++ -o hellosh.exe hellosh.cpp
(3)./hellosh.exe
注意:
(1)调用system需包含头文件#include &lt;cstdlib>,不是cstdlib.h
man system可查看需要system包含在哪个头文件里,新版无.h
 
4、linux C++ 打开文件、写入内容
#include<iostream>  
#include<fstream>
#include<iomanip>
using namespace std;
int main()
{   
    ofstream myfile("myinfo.txt");

    if(!myfile) return 0;  //若打开错误则返回
    myfile<&lt;setw(20)&lt;&lt;"name:"&lt;&lt;"ZhangSan"&lt;&lt;endl;
    myfile&lt;&lt;setw(20)&lt;&lt;"address:"&lt;&lt;"china"&lt;&lt;endl;

    myfile.close();

    return 0;
}
 
5、linux c++读取文件内容
#include&lt;iostream>  
#include<cstdlib>
#include<fstream>
#include<iomanip>
using namespace std;
int main()
{   
   
    fstream myfile("myinfo.txt");
    myfile<&lt;1234;
    myfile.close();

    myfile.open("myinfo.txt");

    int myint;
    myfile>&gt;myint;
    cout<&lt;myint&lt;&lt;endl;

    myfile.close();
    return 0;
}
 
注意:非法操作可能会出现乱码,原因可能是文件没有正常打开和关闭。
 
6、
FindNotAllowedMACsh.cpp
/***************代码说明**************************
1、written by 2012/4/4 QQ
2、将arpMACTemp.txt中的MAC与AllowMACTemp.txt中的MAC进行比对;
找出arpMACTemp.txt中不在AllowMAC.txt列表里的MAC。
3、将找出的MAC存放在NotAllowedMAC.txt中。
4、若NotAllowedMAC.txt不为空,则将该文件内容发给794138953@qq.com
5、该段代码与ExtractarpAndAllowMAC.sh及AllowMAC.txt关联。
****************代码说明**************************/
#include&lt;iostream>  
#include<cstdlib>
#include<fstream>
#include<iomanip>
#include<string>
using namespace std;
int main()
{
        /*ExtractarpAndAllowMAC.sh从文件arpTemp.txt和AllowMAC.txt
        中分别提取出MAC并存放在arpMACTemp.txt和AllowMACTemp.txt中。*/
        system("./ExtractarpAndAllowMAC.sh");
        fstream FilearpMAC("arpMACTemp.txt");
        fstream FileAllowMAC("AllowMACTemp.txt");
        /*************************************
        ExtractarpAndAllowMAC.sh中已经判断并创建则无需这两句
        system("rm NotAllowedMAC.txt");
        system("touch NotAllowedMAC.txt");
        **************************************/
        fstream FileNotAllowedMAC("NotAllowedMAC.txt");
        string StrarpMAC;
        string StrAllowMAC;
        /*************************************
        加下面两句结果会出错
        //FilearpMAC.open("arpMACTemp.txt");
        //FileNotAllowedMAC.open("NotAllowedMAC");
        **************************************/
        while(getline(FilearpMAC,StrarpMAC))
        {
                /*********************************
                //每次外部循环都重新打开ALlowMAC.txt;
                //这样getline()从文件首行开始读;
                //否则getline()读到的是上次的行位置。
                **********************************/
                //FileAllowMAC.open("AllowMACTemp.txt");//这句替换下句会出错!!!
                fstream FileAllowMAC("AllowMACTemp.txt");
                while(getline(FileAllowMAC,StrAllowMAC))
                {
                        if(StrarpMAC==StrAllowMAC)
                                break;
                        else
                                continue;
                }
                //FileAllowMAC.close();//这句没有调试暂未出错!
                if(StrarpMAC==StrAllowMAC)
                        ;
                else
                {
                        cout<&lt;StrarpMAC&lt;&lt;endl;
                        FileNotAllowedMAC&lt;&lt;StrarpMAC&lt;&lt;endl;
                }
        }
        FilearpMAC.close();
        FileAllowMAC.close();
        FileNotAllowedMAC.close();
        system("rm arpMACTemp.txt");
        system("rm AllowMACTemp.txt");
        //判断NotAllowedMAC.txt是否为空,不为空则发送邮件
        fstream FileEmptyOrNot("NotAllowedMAC.txt");
        FileEmptyOrNot.seekg(0,ios::end);
        if(FileEmptyOrNot.tellg()==0)
        {
                cout&lt;&lt;"The file is empty!"&lt;&lt;endl;
        }
        else
        {
                cout&lt;&lt;"The mail has been send!"&lt;&lt;endl;
                //system("mail -s "UnknowMAC" 794138953@qq.com &lt; NotAllowedMAC.txt");
        }
        FileEmptyOrNot.close();
        return 0;
}
 
注:arpMACTemp.txt内容都显示出或得到不期望结果的可能原因:
(1)chmod 644 arpMACTemp.txt AllowMACTemp.txt
(2)在内层循环开始前的语句
fstream FileAllowMAC("AllowMACTemp.txt"); //这句很重要!!!
很重要,无这句,则内层循环开始后不是从AllowMACTemp.txt的首行开始读的!
(3)其他错误的可能原因:C++中文件的定义,open,close用的不正确!
7、
ExtractarpAndAllowMAC.sh
#!/bin/bash
###脚本说明
#written by 2012/4/4 QQ
#1、将命令arp显示的内容重定向到arpTemp.txt中;
#再从arpTemp.txt中提取出MAC按行追加到arpMAC.txt中。
#2、从AllowMAC.txt中提出出MAC按行存放在AllowMACTemp.txt中。
#3、该脚本与AllowMAC.txt关联。
#4、创建NotAllowedMAC.txt供FindNotAllowedMACsh.cpp使用。
###脚本说明
/bin/touch arpTemp.txt
/usr/sbin/arp > arpTemp.txt
if [ -a arpMACTemp.txt ];then
    rm arpMACTemp.txt
else
    /bin/touch arpMACTemp.txt
fi
if [ -a NotAllowedMAC.txt ];then
    rm NotAllowedMAC.txt
else
    /bin/touch NotAllowedMAC.txt
fi
/bin/cat arpTemp.txt | while read arpMACLINE 
do
arpMAC=`echo $arpMACLINE | awk '{print $3}'`
#下面的if else是为了避免将提取出的“硬件地址”这个字符串追加到arpMAC.txt中
if [ $arpMAC = "硬件地址" ];then
    :
else
    echo $arpMAC &gt;&gt; arpMACTemp.txt
fi
done
/bin/rm arpTemp.txt
if [ -a AllowMACTemp.txt ];then
    rm AllowMACTemp.txt
else
    /bin/touch AllowMACTemp.txt
fi
/bin/cat AllowMAC.txt | while read AllowMACLINE 
do
allowmac=`echo $AllowMACLINE | awk '{print $1}'`
    echo $allowmac &gt;&gt; AllowMACTemp.txt
done
 
 
StartFind.sh
#!/bin/bash
####脚本说明####

#编译FindNotAllowedMACsh.cpp
#执行FindNotAllowedMACsh.exe
#删除FindNotAllowedMACsh.exe
#将该脚本放于/etc/crontab中周期执行
####脚本说明####
#mkdir ~/script
#mkdir ~/script/FindNotAllowedMAC
g++ -o ./FindNotAllowedMACsh.exe ./FindNotAllowedMACsh.cpp
./FindNotAllowedMACsh.exe
rm ./FindNotAllowedMACsh.exe
 
8、
OpenFileAndWrite.cpp
#include<iostream>  
#include<cstdlib>
#include<fstream>
#include<iomanip>
using namespace std;
int main()
{   
    ofstream myfile("myinfo.txt");
    if(!myfile) return 0;
    myfile<&lt;setw(20)&lt;&lt;"name:"&lt;&lt;"fys"&lt;&lt;endl;
    myfile&lt;&lt;setw(20)&lt;&lt;"address:"&lt;&lt;"china"&lt;&lt;endl;
    myfile.close();
    return 0;
}
 
9、
OpenFileAndRead.cpp
#include&lt;iostream>  
#include<cstdlib>
#include<fstream>
#include<iomanip>
using namespace std;
int main()
{   
    fstream myfile("myinfo.txt");
    myfile<&lt;1234;
    myfile.close();
    myfile.open("myinfo.txt");
    int myint;
    myfile>&gt;myint;
    cout<&lt;myint&lt;&lt;endl;
    myfile.close();
    return 0;
}

 

10、

基本形式:printf(“格式控制字符串”,变量列表);

#include    &lt;stdio.h>
void main()
{
    printf("%d%d",10,20);
    printf("\n");
    printf("%d%d\n",10,20);
    printf("%d %d      有符号十进制整数\n",10,20);        //%d有符号十进制整数      
    printf("%u %u      无符号十进制整数\n",-10,20);       //%u无符号十进制整数
    printf("%f %f      浮点数十进制记法\n",10.0,20.0);   //%f浮点数十进制记法
    printf("%e %e      浮点数e-记数法\n",10.0,20.0);    //%e浮点数e-记数法
    printf("%o %o\n",10,20);                          //%o无符号八进制整数
    printf("%s %s      字符串\n","10","hello");
    printf("%%         输出百分号\n");

}

 

11.

VA_LIST

/*VA_LIST的用法,解决参数个数可变问题*/
#include    <stdio.h>
#include    <stdarg.h>   
void simple_va_fun(int i, ...)
{
    va_list arg_ptr; //这个变量是指向参数的指针
    int j=0;
    int k=0;
    va_start(arg_ptr, i); //va_start宏的第二个参数即i是第一个可变参数的前一个参数,是固定参数。
    j=va_arg(arg_ptr, int); //返回可变参数
    k=va_arg(arg_ptr, int); //返回可变参数
    va_end(arg_ptr); //结束可变参数的获取
    printf("%d %d %d \n", i,j,k);
}
int main()
{
    simple_va_fun(100);
    simple_va_fun(100,200);
    simple_va_fun(100,200,300);
    return 0;
}

/**************
总结:
(1)先定义指向参数的指针变量va_list arg_ptr;
(2)再初始化(1)中变量va_start(arg_ptr, i),第二个参数即i是第一个可变参数的前一个参数,是固定参数;
(3)依次用va_arg获取多个参数;
(4)最后用va_end结束可变参数的获取。
***************/

 

12.

linux C/C++环境搭建

(1)新立得下载eclipse;

(2)启动eclipse,
  (3)选择Help-&gt;Install New Software...,在Work with的框框下复制下面的地址:  http://download.eclipse.org/releases/galileo
(4)在(3)中界面中选择Name一栏选择Collaboration-&gt;Mylyn Bridge: C/C++ Development,安装,重启eclipse。
(5)同上述2、3,选择Programming Languages-&gt;Eclipse C/C++ Developmen,重启。

注:第(3)步请选择一个框,多选可能出错。

 

编译出错:binary not found   解决:先CTRL+B(project—build all) 再 CTRL+F11(run)

13、

多线程

MultiThreading.c

#include <pthread.h>
#include <stdio.h>
#include <sys/time.h>
#include <string.h>

#define MAX 10
pthread_t thread[2];//线程ID
pthread_mutex_t mut;//定义互斥锁变量
int number=0, i;

void *thread1()
{
    printf ("thread1 : I'm thread 1\n");
    for (i = 0; i < MAX; i++)
    {
        printf("thread1 : number = %d\n",number);
        pthread_mutex_lock(&mut); //上锁,即只允许thread1使用共享资源
        number++;
        pthread_mutex_unlock(&mut); //解锁,其他线程可使用共享资源
        sleep(2);
    }

    printf("thread1 :主函数在等我完成任务吗?\n");
    pthread_exit(NULL);
}

void *thread2()
{
        printf("thread2 : I'm thread 2\n");
        for (i = 0; i &lt; MAX; i++)
        {
            printf("thread2 : number = %d\n",number);
            pthread_mutex_lock(&mut);
            number++;
            pthread_mutex_unlock(&mut);
            sleep(3);
        }

        printf("thread2 :主函数在等我完成任务吗?\n");
        pthread_exit(NULL);
}

/*创建线程*/
void thread_create(void)
{
        int temp;
        memset(&thread, 0, sizeof(thread));       

        if((temp = pthread_create(&thread[0], NULL, thread1, NULL)) != 0)    
            printf("线程1创建失败!\n");
        else
            printf("线程1被创建\n");

        if((temp = pthread_create(&thread[1], NULL, thread2, NULL)) != 0) 
            printf("线程2创建失败");
        else
            printf("线程2被创建\n");
}
/*创建线程*/

/*等待线程结束*/
/*代码中如果没有pthread_join主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。加入pthread_join后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线程有机会执行。*/
void thread_wait(void)
{
        if(thread[0] !=0)
        {                 
            pthread_join(thread[0],NULL);
            printf("线程1已经结束\n");
        }

        if(thread[1] !=0)
        {              
            pthread_join(thread[1],NULL);
            printf("线程2已经结束\n");
        }
}
/*等待线程结束*/

int main()
{
        pthread_mutex_init(&mut,NULL);  //用默认属性初始化互斥锁
        printf("我是主函数哦,我正在创建线程,呵呵\n");

        thread_create();
        printf("我是主函数哦,我正在等待线程完成任务阿,呵呵\n");
        thread_wait();

        return 0;
}

 

编译

gcc -lpthread -o MultiThreading.exe MultiThreading.c

./ MultiThreading.exe

 

SOCKET编程

1.包裹函数

实际程序要检查每个返回值是否正确,包裹函数的作用是调用实际函数,并检查返回值,约定包裹函数名大写实际函数名的第一个字符。

2.无连接套接字

(1)文本文档建立client.c

/*无连接套接子客户端*/

#include &lt;stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>

#define REMOTEPORT 4567
#define REMOTEIP "127.0.0.1"

/*
所在头文件:#include <strings.h>
函数原型:extern void bzero(void *s, int n);
函数功能:置字节字符串s的前n个字节为零且包括‘\0’。
入口参数:字符串,整型。
出口参数:无返回值。
*/

/*
所在头文件:#include <arpa/inet.h>
函数原型:in_addr_t inet_addr(const char *cp);
函数功能:将一个点间隔地址转换成一个in_addr。
入口参数:点间隔地址字符串。
出口参数:in_addr 型地址。
*/

/*
所在头文件:#include <unistd.h>
函数原型:ssize_t read(int fd, void *buf, size_t count);
函数功能:从文件流描述符fd中读数据到buf中,长度不超过count
入口参数:文件流描述符,缓存,长度
出口参数:读到的字符总长度。
*/

/*
所在头文件:#include < sys/types.h > #include < sys/socket.h >
函数原型:int sendto (int s,void * msg,int len, unsigned int flags,struct sockaddr *to,int tolen);
函数功能:将本机编号为s的套接字字符串msg发送给to套接字结构体所代表的地址及端口;
入口参数:s--socket编号,msg--需要发送的字符串,len--发送的字符串长度,flags--一般置0,to--套接子结构体类型,tolen--套接字结构体长度;
出口参数:传送成功,返回传送的字符个数;失败,返回-1。
*/

int main(int argc,char *argv[])
{
    int s,len;
    struct sockaddr_in addr;//套接字数据类型,用来存放一个套接字,这里是目的套接字
    int addr_len;
    char msg[256];   
    int i=0;
    /*if else创建本地即客户端套接字*/
    if(( s = socket(AF_INET,SOCK_DGRAM,0))<0) //创建套接字,返回套接字编号
    {
        perror("error");
        exit(1);
    }
    else
    {
        printf("socket created successfully!\n");
        printf("socket id:%d\n",s);
        printf("remote ip:%s\n",REMOTEIP);
        printf("remote port: %d\n\n",REMOTEPORT);
    }
    /*if else创建本地即客户端套接字*/

    addr_len=sizeof(struct sockaddr_in);
    bzero(&addr,sizeof(addr));
    /*创建外地即服务端套接字*/
    addr.sin_family=AF_INET;
    addr.sin_port=htons(REMOTEPORT);
    addr.sin_addr.s_addr=inet_addr(REMOTEIP);
    /*创建外地即服务端套接字*/

    while(1)
    {
        bzero(msg,sizeof(msg));

        printf("Please Input message\n");
        printf("The serial number of the message:%d\n",i);
        i++;
        len=read(STDIN_FILENO,msg,sizeof(msg));//从键盘(终端)键入msg

        sendto(s,msg,len,0,&addr,addr_len);//发送msg给目的套接字addr
        printf("Send message from client:%s",msg);

        len=recvfrom(s,msg,sizeof(msg),0,&addr,&addr_len);//接受目的套接字传来的msg

        printf("Received message from server:%s\n",msg);
    }

}

(2)文本文档建立server.c

/*无连接套接子服务端*/

#include &lt;stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>

#define LOCALPORT 4567

int main(int argc,char *argv[])
{
    int mysock,len;
    struct sockaddr_in addr;
    int i=0;
    char msg[256];
    int addr_len;
    /*创建本地即服务端套接字*/
    if((mysock=socket(AF_INET,SOCK_DGRAM,0))<0)
    {
        perror("error");
        exit(1);
    }
    else
    {
        printf("socket created successfully!\n");
        printf("socked id:%d\n",mysock);
    }
    /*创建本地即服务端套接字*/
    addr_len=sizeof(struct sockaddr_in);
    bzero(&addr,sizeof(addr));

    /*创建外地即客户端套接字*/
    addr.sin_family=AF_INET;
    addr.sin_port=htons(LOCALPORT);
    addr.sin_addr.s_addr=htonl(INADDR_ANY);//INADDR_ANY 0.0.0.0 即任意地址
    /*创建外地即客户端套接字*/
    /*本地与外地进行绑定,服务器在绑定端口上监听信息*/
    if(bind(mysock,&addr,sizeof(addr))&lt;0)
    {
        perror("error");
        exit(1);
    }
    else
    {
        printf("bind successfully!\n");       
        printf("local port:%d \n\n",LOCALPORT);
    }
    /*本地与外地进行绑定,服务器在绑定端口上监听信息*/

    while(1)
    {
        bzero(msg,sizeof(msg));
        len=recvfrom(mysock,msg,sizeof(msg),0,&addr,&addr_len);
        printf("The serial number of the message:%d\n",i);
        i++;

        printf("The message Received from client:%s",msg);
        printf("Received message length:%d\n",len);
        printf("Received message from:%s\n",inet_ntoa(addr.sin_addr));
        printf("Reply message from server:%s\n",msg);
        sendto(mysock,msg,len,0,&addr,addr_len);
    }
}

(3)运行

在同一台机子上测试,client发送消息给server,server返回应答消息

在一个终端输入

gcc –o server.exe server.c

./server.exe

 

另一个终端输入

gcc –o client.exe client.c

./client.exe

注:只是设定了server的端口和IP,没有设定client的端口和IP

对client只需知道server的端口和IP

对server上面程序是监听LOCALPORT端口,接收IP为INADDR_ANY

编译时可能会出现如下类似warning,注意是warning,不是errors,仍可运行

root@ubuntu:~/workspaceCDT/NoConnectionSocket# gcc -o server.exe server.c
server.c: In function ‘main’:
server.c:23: warning: incompatible implicit declaration of built-in function ‘exit’
server.c:34: warning: incompatible implicit declaration of built-in function ‘bzero’
server.c:43: warning: passing argument 2 of ‘bind’ from incompatible pointer type
/usr/include/sys/socket.h:115: note: expected ‘const struct sockaddr *’ but argument is of type ‘struct sockaddr_in *’
server.c:46: warning: incompatible implicit declaration of built-in function ‘exit’
server.c:58: warning: passing argument 5 of ‘recvfrom’ from incompatible pointer type
/usr/include/sys/socket.h:166: note: expected ‘struct sockaddr * __restrict__’ but argument is of type ‘struct sockaddr_in *’
server.c:68: warning: passing argument 5 of ‘sendto’ from incompatible pointer type
/usr/include/sys/socket.h:155: note: expected ‘const struct sockaddr *’ but argument is of type ‘struct sockaddr_in *’

原因是传参时的类型不一致

所以将server.c:43行改为if(bind(mysock,(struct sockaddr *)&addr,sizeof(addr))&lt;0)则可消除此行警告。

另外出现如下incompatible implicit declaration of built-in function ….的原因是没有添加相应头文件

如下行是没有添加头文件stdio.h

incompatible implicit declaration of built-in function ‘printf’

如下行是没有添加头文件string.h

incompatible implicit declaration of built-in function ‘bzero’

最终的无连接套接字client.c和 server.c的程序如下

(1)client.c

#include &lt;stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>

#define REMOTEPORT 4567
#define REMOTEIP "127.0.0.1"//这是server端的IP,如在两台机器上测试,只需更改此IP为server端IP

/*
所在头文件:#include <strings.h>
函数原型:extern void bzero(void *s, int n);
函数功能:置字节字符串s的前n个字节为零且包括‘\0’。
入口参数:字符串,整型。
出口参数:无返回值。
*/

/*
所在头文件:#include <arpa/inet.h>
函数原型:in_addr_t inet_addr(const char *cp);
函数功能:将一个点间隔地址转换成一个in_addr。
入口参数:点间隔地址字符串。
出口参数:in_addr 型地址。
*/

/*
所在头文件:#include <unistd.h>
函数原型:ssize_t read(int fd, void *buf, size_t count);
函数功能:从文件流描述符fd中读数据到buf中,长度不超过count
入口参数:文件流描述符,缓存,长度
出口参数:读到的字符总长度。
*/

/*
所在头文件:#include < sys/types.h > #include < sys/socket.h >
函数原型:int sendto (int s,void * msg,int len, unsigned int flags,struct sockaddr *to,int tolen);
函数功能:将本机编号为s的套接字字符串msg发送给to套接字结构体所代表的地址及端口;
入口参数:s--socket编号,msg--需要发送的字符串,len--发送的字符串长度,flags--一般置0,to--套接子结构体类型,tolen--套接字结构体长度;
出口参数:传送成功,返回传送的字符个数;失败,返回-1。
*/

int main(int argc,char *argv[])
{
    int s,len;
    struct sockaddr_in addr;//套接字数据类型,用来存放一个套接字,这里是目的套接字
    int addr_len;
    char msg[256];   
    int i=0;
    /*if else创建本地即客户端套接字*/
    if(( s = socket(AF_INET,SOCK_DGRAM,0))<0) //创建套接字,返回套接字编号
    {
        perror("error");
        exit(1);
    }
    else
    {
        printf("socket created successfully!\n");
        printf("socket id:%d\n",s);
        printf("remote ip:%s\n",REMOTEIP);
        printf("remote port: %d\n\n",REMOTEPORT);
    }
    /*if else创建本地即客户端套接字*/

    addr_len=sizeof(struct sockaddr_in);
    bzero(&addr,sizeof(addr));
    /*外地即服务端套接字*/
    addr.sin_family=AF_INET;
    addr.sin_port=htons(REMOTEPORT);
    addr.sin_addr.s_addr=inet_addr(REMOTEIP);
    /*外地即服务端套接字*/

    while(1)
    {
        bzero(msg,sizeof(msg));

        printf("Please Input message\n");
        printf("The serial number of the message:%d\n",i);
        i++;
        len=read(STDIN_FILENO,msg,sizeof(msg));//从键盘(终端)键入msg

        sendto(s,msg,len,0,(struct sockaddr *)&addr,addr_len);//发送msg给目的套接字addr
        printf("Send message from client:%s",msg);

        len=recvfrom(s,msg,sizeof(msg),0,(struct sockaddr *)&addr,&addr_len);//接受目的套接字传来的msg

        printf("Received message from server:%s\n",msg);
    }

}

(2)server.c

#include &lt;stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/socket.h>

#define LOCALPORT 4567

int main(int argc,char *argv[])
{
    int mysock,len;
    struct sockaddr_in addr;
    int i=0;
    char msg[256];
    int addr_len;
    /*创建本地即服务端套接字*/
    if((mysock=socket(AF_INET,SOCK_DGRAM,0))<0)
    {
        perror("error");
        exit(1);
    }
    else
    {
        printf("socket created successfully!\n");
        printf("socked id:%d\n",mysock);
    }
    /*创建本地即服务端套接字*/
    addr_len=sizeof(struct sockaddr_in);
    bzero(&addr,sizeof(addr));

    /*本地即server套接字属性*/
    addr.sin_family=AF_INET;
    addr.sin_port=htons(LOCALPORT);
    addr.sin_addr.s_addr=htonl(INADDR_ANY);//INADDR_ANY 0.0.0.0 即将地址清零,系统找到的是本机IP
    /*本地即server套接字属性*/
    /*绑定本地server套接字的端口和IP*/
    if(bind(mysock,(struct sockaddr *)&addr,sizeof(addr))&lt;0)
    {
        perror("error");
        exit(1);
    }
    else
    {
        printf("bind successfully!\n");       
        printf("local port:%d \n\n",LOCALPORT);
    }
    /*绑定本地server套接字的端口和IP*/

    while(1)
    {
        bzero(msg,sizeof(msg));
        len=recvfrom(mysock,msg,sizeof(msg),0,(struct sockaddr *)&addr,&addr_len);
        printf("The serial number of the message:%d\n",i);
        i++;

        printf("The message Received from client:%s",msg);
        printf("Received message length:%d\n",len);
        printf("Received message from:%s\n",inet_ntoa(addr.sin_addr));
        printf("Reply message from server:%s\n",msg);
        sendto(mysock,msg,len,0,(struct sockaddr *)&addr,addr_len);
    }
}

3.面向连接套接字

(1)client.c

#include &lt;stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>

#define PORT 5678
#define REMOTE_IP "127.0.0.1"

int main()
{
    int s;
    struct sockaddr_in addr;
    char mybuffer[256];

    if((s=socket(AF_INET,SOCK_STREAM,0))<0)
    {
        perror("socket");
        exit(1);
    }
    else
    {
        printf("socket created successfully!.\n");
        printf("socked id:%d\n",s);
    }

    bzero(&addr,sizeof(addr));
    addr.sin_family=AF_INET;
    addr.sin_port=htons(PORT);
    addr.sin_addr.s_addr=inet_addr(REMOTE_IP);

    if(connect(s,(struct sockaddr *)&addr,sizeof(addr))&lt;0)
    {
        perror("connect");
        exit(1);
    }
    else
    {
        printf("connected ok!\n");
        printf("remote ip:%s\n",REMOTE_IP);
        printf("remote port:%d\n",PORT);
    }

    recv(s,mybuffer,sizeof(mybuffer),0);
    printf("%s\n",mybuffer);
    while(1)
    {
        bzero(mybuffer,sizeof(mybuffer));
        read(STDIN_FILENO,mybuffer,sizeof(mybuffer));//从键盘读信息
        /*发送并接收数据(if else意思是发送成功则执行接收,发送失败则退出)*/
        if(send(s,mybuffer,sizeof(mybuffer),0)&lt;0)//发送从键盘读到的信息
        {
            perror("send");
            exit(1);
        }
        else
        {
            bzero(mybuffer,sizeof(mybuffer));
            recv(s,mybuffer,sizeof(mybuffer),0);//接收server端的信息
            printf("received from server:%s\n",mybuffer);
        }
        /*发送并接收数据(if else意思是发送成功则执行接收,发送失败则退出)*/
    }
}

(2)

server.c

#include &lt;stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#define PORT 5678
#define MAX 10

/*面向连接套接字server端*/

/*
所在头文件:#include <sys/select.h>
函数原型:int select(int nfds, fd_set *readfds, fd_set *writefds,fd_set *exceptfds, struct timeval *timeout);
函数功能:一个进程同时处理多个文件描述符是很常见的情况。
入口参数:
出口参数:1、正常情况返回就绪的文件描述符个数;2、timeout时长无设备准备好,返回0;3、若select被某个信号中断,返回-1,并设置errno为EINTR;4、若出错,则返回-1,并设置相应的errno。
*/
int main()
{
    int sockfd,newsockfd,is_connected[MAX],fd;
    struct sockaddr_in addr;
    int addr_len = sizeof(struct sockaddr_in);
    fd_set myreadfds;//定义文件描述符集合
    char msgbuffer[256];
    char msg[]="The message is from server:connected successfully.\n";
    /*创建本地套接字*/
    if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
    {
        perror("socket");
        exit(1);
    }
    else
    {   
        printf("socket created successfully!\n");
        printf("socket id:%d\n",sockfd);
    }
    /*创建本地套接字*/
    /*允许地址重用*/
    int ret,on;
    on=1;
    ret=setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
    /*允许地址重用*/

    /*本地套接子属性*/
    bzero(&addr,sizeof(addr));
    addr.sin_family=AF_INET;
    addr.sin_port=htons(PORT);
    addr.sin_addr.s_addr=htonl(INADDR_ANY);
    /*本地套接子属性*/

    /*绑定本地套接子端口和IP等属性*/
    if(bind(sockfd,(struct sockaddr *)&addr,sizeof(addr))&lt;0)
    {
        perror("connect");
    }
    else
    {
        printf("connected successfully!\n");
        printf("local port:%d\n",PORT);
    }
    /*绑定本地套接子端口和IP等属性*/

    /*server监听,等待client连接,最大连接数为3*/
    if(listen(sockfd,3)&lt;0)
    {
        perror("listen");
        exit(1);
    }
    else
    {
        printf("listening......\n");
    }
    /*server监听,等待client连接,最大连接数为3*/
    for(fd=0;fd&lt;MAX;fd++)
    {
        is_connected[fd]=0;
    }

    while(1)
    {
        FD_ZERO(&myreadfds);//文件描述符集合中所有位置0
        FD_SET(sockfd,&myreadfds);//将文件描述符的sockfd位置1(本地套接字位置1)
        for(fd=0;fd&lt;MAX;fd++)
        {
            if(is_connected[fd])
            {
                FD_SET(fd,&myreadfds);
            }
        }
        if(!select(MAX,&myreadfds,NULL,NULL,NULL))
        {
            continue;
        }
        for(fd=0;fd&lt;MAX;fd++)   
        {
            if(FD_ISSET(fd,&myreadfds))           
            {   
                if(sockfd==fd)
                {
                    if((newsockfd=accept(sockfd,(struct sockaddr *)&addr,&addr_len))&lt;0)
                    {
                        perror("accept");
                    }
                    write(newsockfd,msg,sizeof(msg));//给客户端发送信息
                    is_connected[newsockfd]=1;
                    printf("connect from%s\n",inet_ntoa(addr.sin_addr));
                }
                else
                {   
                    bzero(msgbuffer,sizeof(msgbuffer));
                    if(read(fd,msgbuffer,sizeof(msgbuffer))&lt;=0)
                    {
                        printf("connect closed.\n");
                        is_connected[fd]=0;
                        close(fd);
                    }
                    else
                    {
                        write(fd,msgbuffer,sizeof(msgbuffer));
                        printf("message:%s\n",msgbuffer);
                    }
                }
            }
        }
    }
}

(3)运行

gcc –o client.exe client.c

gcc –o server.exe server.c

在两个终端分别运行./client.c    ./server.c

client.c终端输入字符串

且先运行server

 

套接字编程补充:

1、socket函数

#include &lt;sys/socket.h>

int socket(int family,int type,int protocol);

功能:

创建一个套接口

入口:

family——指明协议族,一般是AF_INET(IPv4协议);

type——有SOCK_STREAM、SOCK_DGRAM、SOCK_SEQPACKET、SOCK_RAW;

protocol——IPPROTO_TCP  IPPROTO_UDP  IPPROTO_SCTP

出口:

正确,套接字字符描述符,非负整数;出错,-1

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值