C语言Socket-单工通信(客户端向服务器发送数据)

服务端(server)

#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")    //把ws2_32.lib加到Link页的连接库
#define PORT 15001                    //通信的端口(指服务器端)
#define ERROR 0
#define BUFFER_SIZE 1024            //注意:此Server端数据接收缓冲区 >= Client端数据发送缓冲区 ,否则造成缓冲区溢出
/*
    服务端原理:
        1、服务器进程创建套接字
        2、将本地地址绑定到所创建的套接字上,以三元组{<通信协议>,<IP地址>,<端口号>}在网络上标识该套接字
        3、将套接字置入监听模式,并准备接受连接请求
*/
int main()
{
    WSADATA WSAData;
    if(WSAStartup(MAKEWORD(2,0),&WSAData)==SOCKET_ERROR)  //启动winsock ,WSAStartup()函数对Winsock DLL进行初始化
    {
        printf("Socket initialize fail!\n");
        exit(1);
    }
    SOCKET sock;                                        //服务进程创建套接字句柄(用于监听)
    if((sock=socket(AF_INET,SOCK_STREAM,0))==ERROR)        //调用socket()函数创建一个流套接字,参数(网络地址类型,套接字类型,网络协议)
    {
        printf("Socket create!\n");
        WSACleanup();
        exit(1);
    }
    struct sockaddr_in ServerAddr;            //sockaddr_in结构用来标识TCP/IP协议下的地址,可强制转换为sockaddr结构
    ServerAddr.sin_family=AF_INET;            //sin_family字段必须设为AF_INET,表示该Socket处于Internet域
    ServerAddr.sin_port=htons(PORT);        //sin_port字段用于指定服务端口,注意避免冲突
    ServerAddr.sin_addr.s_addr=INADDR_ANY;  //sin_addr字段用于把一个IP地址保存为一个4字节的数,无符号长整型,根据不同用法还可表示本地或远程IP地址
    if(bind(sock,(LPSOCKADDR)&ServerAddr,sizeof(ServerAddr))==SOCKET_ERROR)  //调用bind()函数将本地地址绑定到所创建的套接字上,以在网络上标识该套接字
    {
        printf("Bind fail!\n");
        closesocket(sock);
        WSACleanup();
        exit(1);
    }
    printf("Server Socket Port:%d\n",ntohs(ServerAddr.sin_port));
    if(listen(sock,10)==SOCKET_ERROR)        //调用listen()函数将套接字置入监听模式并准备接受连接请求,参数(已捆绑未连接的套接字描述字,正在等待连接的最大队列长度)
    {
        printf("Listen fail!\n");
        closesocket(sock);
        WSACleanup();
        exit(1);
    }  

    SOCKET msgsock;            //创建一个新的套接字(用于接收accept函数的返回值,即表示已经接受的那个客户端的连接,进而接收Client发来的数据)
    char buf[BUFFER_SIZE];  //数据接收缓冲区
    while(1)
    {
        if((msgsock=accept(sock,(LPSOCKADDR)0,(int *)0))==INVALID_SOCKET)  //进入监听状态后,调用accept()函数接收客户端的连接请求,并把连接传给msgsock套接字,原sock套接字继续监听其他客户机连接请求
        {
            printf("Accept fail!\n");
            continue;
        }
        memset(buf,0,sizeof(buf));                                            //初始化数据接收缓冲区
        recv(msgsock,buf,BUFFER_SIZE,0);                                    //接收客户端发送过来的数据
        if(buf[0]==‘e‘ && buf[1]==‘x‘ && buf[2]==‘i‘ && buf[3]==‘t‘)        //"exit"命令,退出程序
        {
            printf("The End.\n");
            break;
        }
        printf("C:\\Socket\\Server>%s",buf);
        closesocket(msgsock);
    }  

    closesocket(sock); //关闭套接字
    WSACleanup();       //终止对Winsock DLL的使用,并释放资源
    return 0;
}   

客户端(client)

#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")    //把ws2_32.lib加到Link页的连接库
//#define IP "172.18.68.243"            //在两台计算机上测试,IP为Server端的IP地址
#define IP "127.0.0.1"                //在一台计算机上测试,IP为本地回送地址
#define PORT 15001                    //注意:客户端设置通信的端口 = 服务端的端口
#define BUFFER_SIZE 1024            //数据发送缓冲区大小

int main()
{
    char buf[BUFFER_SIZE];                                //buf数组存放客户端发送的消息
    int inputLen;                                        //用于输入字符自增变量
    while(1)
    {
        printf("C:\\Socket\\Client>");
        inputLen=0;
        memset(buf,0,sizeof(buf));
        while((buf[inputLen++]=getchar())!=‘\n‘)        //输入以回车键为结束标识
        {
            ;
        }
        if(buf[0]==‘e‘ && buf[1]==‘x‘ && buf[2]==‘i‘ && buf[3]==‘t‘)
        {
            printf("The End.\n");
            break;
        }  

        WSADATA WSAData;
        if(WSAStartup(MAKEWORD(2,0),&WSAData)==SOCKET_ERROR)  //WSAStartup()函数对Winsock DLL进行初始化
        {
            printf("Socket initialize fail!\n");
            continue;
        }
        SOCKET sock;                                            //客户端进程创建套接字
        if((sock=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR)  //创建流套接字(与服务端保持一致)
        {
            printf("Socket create fail!\n");
            WSACleanup();
            continue;
        }  

        struct sockaddr_in ClientAddr;                //sockaddr_in结构用来标识TCP/IP协议下的地址,可强制转换为sockaddr结构
        ClientAddr.sin_family=AF_INET;                //指Internet域
        ClientAddr.sin_port=htons(PORT);            //指定服务端所预留的端口
        ClientAddr.sin_addr.s_addr=inet_addr(IP);    //指定服务端所绑定的IP地址
        if(connect(sock,(LPSOCKADDR)&ClientAddr,sizeof(ClientAddr))==SOCKET_ERROR)  //调用connect()函数,向服务器进程发出连接请求
        {
            printf("Connect fail!\n");
            closesocket(sock);
            WSACleanup();
            continue;
        }
        send(sock,buf,BUFFER_SIZE,0);                 //向服务器发送数据
        closesocket(sock);                             //关闭套接字
        WSACleanup();                                //终止对Winsock DLL的使用,并释放资源,以备下一次使用
    }
    return 0;
}  

参考文献:https://blog.csdn.net/lynch0571

原文地址:https://www.cnblogs.com/LyShark/p/9158656.html

时间: 2024-10-01 07:36:08

C语言Socket-单工通信(客户端向服务器发送数据)的相关文章

一个客户端向服务器发送数据,服务器向连接的客户端转发数据demo

服务端代码: // 负责处理每个线程通信的线程类 public class ServerThread implements Runnable { // 定义当前线程所处理的Socket Socket s = null; // 该线程所处理的Socket所对应的输入流 BufferedReader br = null; public ServerThread(Socket s) throws IOException { this.s = s; // 初始化该Socket对应的输入流 br = ne

C语言 Socket入门示例1—— 单工通信(客户端向服务器发送消息)

如果对Windows API不太熟悉.对TCP/IP通信协议不太熟悉,或者对C语言本身不太熟悉的话,学习Socket会有点难受的.以前学习操作系统的时候,被API吓怕了,很多莫名其妙的API有着多如牛毛的参数,令人费解.学习计算机网络的时候,又有那么多的协议,并且很多协议本身比较复杂,什么三次握手建立连接,什么四次握手释放链接等等,也没有学得特别透彻.更遗憾的是,以前学C的时候,误以为自己把C学会了,误以为C就那么几个头文件而已,就一个黑框子而已. 现在,经过一段时间的痛苦磨练,又有了一些新的认

C语言 Socket入门示例2——模拟远程CMD(客户端向服务器发送命令,服务端执行该命令)

只要把上一篇文章"C语言 Socket入门示例1"中的两段程序彻底搞懂,那么再看本文就没有任何难度了,因为仅仅是对上篇文章中服务端代码的简单修改扩充.但是简单修改过后,功能变得异常强大,犹如一个远程CMD.随着不断深入学习,功能将会变得越来越强大.欢迎大家评论指点. 1.服务端(Server): #include <stdio.h> #include <winsock2.h> #pragma comment(lib,"ws2_32.lib")

C语言Socket-模拟远程CMD(客户端向服务器发送命令,服务器执行该命令)

服务端(server) #include <stdio.h> #include <winsock2.h> #pragma comment(lib,"ws2_32.lib") //把ws2_32.lib加到Link页的连接库 #define PORT 15001 //通信的端口(指服务器端) #define ERROR 0 #define BUFFER_SIZE 1024 //注意:此Server端数据接收缓冲区 >= Client端数据发送缓冲区 ,否则造

android客户端与服务器交互数据(基于SAOP协议的远程调用标准,通过webservice可以将不同操作系统平台,不同语言,不同技术整合)

在PC机器java客户端中,需要一些库,比如XFire,Axis2,CXF等等来支持访问WebService,但是这些库并不适合我们资源有限的android手机客户端,做过JAVA ME的人都知道有KSOAP这个第三方的类库,可以帮助我们获取服务器端webService调用,当然KSOAP已经提供了基于android版本的jar包 首先下载KSOAP包:ksoap2-android-assembly-2.5.2-jar-with-dependencies.jar包 然后新建android项目 以

java实现客户端向服务器发送文件的操作

服务器源代码: import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket;

介绍一款chrom浏览器插件 DHC是一款使用chrome模拟REST客户端向服务器发送测试数据的谷歌浏览器插件

先打个小广告哈 公司招java架构师,月薪25K以上,负责电商平台架构工作,工作地点在北京 1号线永安里站 附近,如有意向 请把简历发我邮箱[email protected] 可以内部推荐. DHC是一款使用chrome模拟REST客户端向服务器发送测试数据的谷歌浏览器插件. DHC的开发背景 在web开发中,服务器端和客户端的开发和测试必不可少,但是测试的工作往往需要服务器端完成之后,客户端才能进行测试,这无疑延后了测试流程,导致服务器端开发完成后,无法进行充分的数据测试,很容易造成服务器端和

ICE学习第四步-----客户端请求服务器返回数据

这次我们来做一个例子,流程很简单:客户端向服务器发送一条指令,服务端接收到这条指令之后,向客户端发送数据库中查询到的数据,最终显示在DataGridView上. 根据上一篇文章介绍的Slice语法,我们先来定义ICE文件.我定义两个ICE文件,一个用来描述测试数据库表中属性相关信息,另一个则是请求数据的方法. 结构如下:    定义结构体,和数据库中表的列对应,添加序列(相当于数组类型). 在获取表的方法中注意要记得#include带有结构的ice文件,并把接口函数的返回值类型写成之前定义的数组

使用post()方法以POST方式从服务器发送数据

使用post()方法以POST方式从服务器发送数据 与get()方法相比,post()方法多用于以POST方式向服务器发送数据,服务器接收到数据之后,进行处理,并将处理结果返回页面,调用格式如下: $.post(url,[data],[callback]) 参数url为服务器请求地址,可选项data为向服务器请求时发送的数据,可选项callback参数为请求成功后执行的回调函数. 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transiti