实现简单的Socket通信案例(个人尝试)

服务端代码(Server)

#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#define PORT 9999 int main()
{
WSADATA WSAData;
SOCKET sock, msgsock;
struct sockaddr_in ServerAddr; if (WSAStartup(MAKEWORD(, ), &WSAData) != SOCKET_ERROR)
{
ServerAddr.sin_family = AF_INET;
ServerAddr.sin_port = htons(PORT);
ServerAddr.sin_addr.s_addr = INADDR_ANY; sock = socket(AF_INET, SOCK_STREAM, );
int BindRet = bind(sock, (LPSOCKADDR)&ServerAddr, sizeof(ServerAddr));
int LinsRet = listen(sock, );
printf("------------------------------------------------------------------------------------------\n");
printf("绑定状态: %d\t 侦听状态: %d\t 绑定端口: %d\n", BindRet, LinsRet, ntohs(ServerAddr.sin_port));
printf("------------------------------------------------------------------------------------------\n");
} while ()
{
char buf[];
msgsock = accept(sock, (LPSOCKADDR), (int *));
memset(buf, , sizeof(buf));
recv(msgsock, buf, , );
printf("客户IP: %s\t 端口:%d\t 数据:%s\n", inet_ntoa(ServerAddr.sin_addr), htons(ServerAddr.sin_port),buf);
if (!strcmp(buf, "Success"))
{
printf("客户端已就绪...\n");
}
closesocket(msgsock);
}
closesocket(sock);
WSACleanup();
return ;
}

客户端代码(Client)

#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32.lib")
#define IP "127.0.0.1"
#define PORT 9999 //#ifdef _MSC_VER
//#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
//#endif int main()
{
while ()
{
WSADATA WSAData;
SOCKET sock;
struct sockaddr_in ClientAddr; if (WSAStartup(MAKEWORD(, ), &WSAData) != SOCKET_ERROR)
{
ClientAddr.sin_family = AF_INET; //指Internet域
ClientAddr.sin_port = htons(PORT); //指定服务端所预留的端口
ClientAddr.sin_addr.s_addr = inet_addr(IP); //指定服务端所绑定的IP地址 sock = socket(AF_INET, SOCK_STREAM, );
int Ret = connect(sock, (LPSOCKADDR)&ClientAddr, sizeof(ClientAddr));
if (Ret == )
{
char Status[] = "Success";
int ServerRet = send(sock, Status, sizeof(Status), );
if (ServerRet != )
{
printf("发送给服务器Success状态成功..\n");
}
}
}
closesocket(sock);
WSACleanup();
Sleep();
}
return ;
}

实现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(,),&WSAData)==SOCKET_ERROR) //启动winsock ,WSAStartup()函数对Winsock DLL进行初始化
{
printf("Socket initialize fail!\n");
exit();
}
SOCKET sock; //服务进程创建套接字句柄(用于监听)
if((sock=socket(AF_INET,SOCK_STREAM,))==ERROR) //调用socket()函数创建一个流套接字,参数(网络地址类型,套接字类型,网络协议)
{
printf("Socket create!\n");
WSACleanup();
exit();
}
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();
}
printf("Server Socket Port:%d\n",ntohs(ServerAddr.sin_port));
if(listen(sock,)==SOCKET_ERROR) //调用listen()函数将套接字置入监听模式并准备接受连接请求,参数(已捆绑未连接的套接字描述字,正在等待连接的最大队列长度)
{
printf("Listen fail!\n");
closesocket(sock);
WSACleanup();
exit();
} SOCKET msgsock; //创建一个新的套接字(用于接收accept函数的返回值,即表示已经接受的那个客户端的连接,进而接收Client发来的数据)
char buf[BUFFER_SIZE]; //数据接收缓冲区
while()
{
if((msgsock=accept(sock,(LPSOCKADDR),(int *)))==INVALID_SOCKET) //进入监听状态后,调用accept()函数接收客户端的连接请求,并把连接传给msgsock套接字,原sock套接字继续监听其他客户机连接请求
{
printf("Accept fail!\n");
continue;
}
memset(buf,,sizeof(buf)); //初始化数据接收缓冲区
recv(msgsock,buf,BUFFER_SIZE,); //接收客户端发送过来的数据
if(buf[]=='e' && buf[]=='x' && buf[]=='i' && buf[]=='t') //"exit"命令,退出程序
{
printf("The End.\n");
break;
}
printf("C:\\Socket\\Server>%s",buf);
closesocket(msgsock);
} closesocket(sock); //关闭套接字
WSACleanup(); //终止对Winsock DLL的使用,并释放资源
return ;
}

客户端代码(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()
{
printf("C:\\Socket\\Client>");
inputLen=;
memset(buf,,sizeof(buf));
while((buf[inputLen++]=getchar())!='\n') //输入以回车键为结束标识
{
;
}
if(buf[]=='e' && buf[]=='x' && buf[]=='i' && buf[]=='t')
{
printf("The End.\n");
break;
} WSADATA WSAData;
if(WSAStartup(MAKEWORD(,),&WSAData)==SOCKET_ERROR) //WSAStartup()函数对Winsock DLL进行初始化
{
printf("Socket initialize fail!\n");
continue;
}
SOCKET sock; //客户端进程创建套接字
if((sock=socket(AF_INET,SOCK_STREAM,))==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,); //向服务器发送数据
closesocket(sock); //关闭套接字
WSACleanup(); //终止对Winsock DLL的使用,并释放资源,以备下一次使用
}
return ;
}

转载:https://blog.csdn.net/lynch0571

实现Socket双工通信案例

服务端代码(Server)

#include <stdio.h>
#include <Winsock2.h> //Socket的函数调用 
#include <windows.h> #define BUF_SIZE 6400 // 缓冲区大小 #pragma comment (lib, "ws2_32") // 使用WINSOCK2.H时,则需要库文件WS2_32.LIB DWORD WINAPI Rcv(LPVOID lpParam)
{
SOCKET sClient = *(SOCKET*)lpParam;
int retVal;
char bufRecv[BUF_SIZE];
memset(bufRecv, , sizeof(bufRecv));
while ()
{
retVal = recv(sClient, bufRecv, BUF_SIZE, );
if (retVal == SOCKET_ERROR) {
printf("recive faild!\n");
break;
}
else {
printf("收到客户端消息:%s\n", bufRecv);
}
}
return ;
} DWORD WINAPI Snd(LPVOID lpParam)
{
SOCKET sClient = *(SOCKET*)lpParam;
int retVal;
char bufSend[BUF_SIZE];
memset(bufSend, , sizeof(bufSend));
while ()
{
gets(bufSend);
retVal = send(sClient, bufSend, strlen(bufSend) + sizeof(char), );
if (retVal == SOCKET_ERROR) {
printf("send faild!\n");
break;
}
}
return ;
} int main(int argc, char* argv[])
{
// 初始化套接字动态库
WSADATA wsaData;
if (WSAStartup(MAKEWORD(, ), &wsaData) != ) {
printf("winsock load faild!\n");
return ;
} // 创建服务段套接字
SOCKET sServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sServer == INVALID_SOCKET) {
printf("socket faild!\n");
WSACleanup();
return -;
} // 服务端地址
sockaddr_in addrServ; addrServ.sin_family = AF_INET;
addrServ.sin_port = htons();
addrServ.sin_addr.s_addr = htonl(INADDR_ANY); // 绑定套接字
if (bind(sServer, (const struct sockaddr*)&addrServ, sizeof(addrServ)) == SOCKET_ERROR) {
printf("bind faild!\n");
closesocket(sServer);
WSACleanup();
return -;
} printf("Server is On IP:[%s],port:[%d]\n", inet_ntoa(addrServ.sin_addr), ntohs(addrServ.sin_port)); // 监听套接字 数字表示最多能监听客户个数
if (listen(sServer, ) == SOCKET_ERROR) {
printf("listen faild!\n");
closesocket(sServer);
WSACleanup();
return -;
} SOCKET sClient; // 客户端套接字 sockaddr_in addrClient;
int addrClientLen = sizeof(addrClient); sClient = accept(sServer, (sockaddr FAR*)&addrClient, &addrClientLen);
if (sClient == INVALID_SOCKET) {
printf("accept faild!\n");
closesocket(sServer);
WSACleanup();
return -;
}
printf("accepted client IP:[%s],port:[%d]\n", inet_ntoa(addrClient.sin_addr), ntohs(addrClient.sin_port)); HANDLE hThread1, hThread2;
DWORD dwThreadId1, dwThreadId2; hThread1 = ::CreateThread(NULL, NULL, Snd, (LPVOID*)&sClient, , &dwThreadId1);
hThread2 = ::CreateThread(NULL, NULL, Rcv, (LPVOID*)&sClient, , &dwThreadId2); ::WaitForSingleObject(hThread1, INFINITE);
::WaitForSingleObject(hThread2, INFINITE);
::CloseHandle(hThread1);
::CloseHandle(hThread2); closesocket(sClient);
WSACleanup(); // 资源释放 return ;
}

客户端代码(Client)

#include <stdio.h>
#include <Winsock2.h> //Socket的函数调用 
#include <windows.h> #define BUF_SIZE 6400 #pragma comment (lib, "ws2_32") // 使用WINSOCK2.H时,则需要库文件WS2_32.LIB DWORD WINAPI Rcv(LPVOID lpParam)
{
SOCKET sHost = *(SOCKET*)lpParam;
int retVal;
char bufRecv[BUF_SIZE];
memset(bufRecv, , sizeof(bufRecv));
while ()
{
retVal = recv(sHost, bufRecv, BUF_SIZE, );
if (retVal == SOCKET_ERROR) {
printf("recive faild!\n");
break;
}
else {
printf("收到服务器消息:%s\n", bufRecv);
}
}
return ;
} DWORD WINAPI Snd(LPVOID lpParam)
{
SOCKET sHost = *(SOCKET*)lpParam;
int retVal;
char bufSend[BUF_SIZE];
memset(bufSend, , sizeof(bufSend));
while ()
{
gets(bufSend);
retVal = send(sHost, bufSend, strlen(bufSend) + sizeof(char), );
if (retVal == SOCKET_ERROR) {
printf("send faild!\n");
break;
}
}
return ;
} int main(int argc, char* argv[])
{
WSADATA wsaData;
if (WSAStartup(MAKEWORD(, ), &wsaData) != ) {
printf("Winsock load faild!\n");
return ;
} // 服务器套接字
SOCKET sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sHost == INVALID_SOCKET) {
printf("socket faild!\n");
WSACleanup();
return -;
} SOCKADDR_IN servAddr;
servAddr.sin_family = AF_INET;
// 注意 当把客户端程序发到别人的电脑时 此处IP需改为服务器所在电脑的IP
servAddr.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
servAddr.sin_port = htons(); // 连接服务器
if (connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr)) == SOCKET_ERROR) {
printf("connect faild!\n");
closesocket(sHost);
WSACleanup();
return -;
}
printf("连接到服务器 IP:[%s],port:[%d]\n", inet_ntoa(servAddr.sin_addr), ntohs(servAddr.sin_port)); HANDLE hThread1, hThread2;
DWORD dwThreadId1, dwThreadId2; hThread1 = ::CreateThread(NULL, NULL, Snd, (LPVOID)&sHost, , &dwThreadId1);
hThread2 = ::CreateThread(NULL, NULL, Rcv, (LPVOID)&sHost, , &dwThreadId2); ::WaitForSingleObject(hThread1, INFINITE);
::WaitForSingleObject(hThread2, INFINITE);
::CloseHandle(hThread1);
::CloseHandle(hThread2); closesocket(sHost);
WSACleanup();
return ;
}

转载:https://www.cnblogs.com/wuyepeng/

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

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

    服务端(server) #include <stdio.h> #include <winsock2.h> #pragma comment(lib,"ws2_32.li ...

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

    这次我们来做一个例子,流程很简单:客户端向服务器发送一条指令,服务端接收到这条指令之后,向客户端发送数据库中查询到的数据,最终显示在DataGridView上. 根据上一篇文章介绍的Slice语法,我 ...

  3. android客户端向服务器发送请求中文乱码的问

    android客户端向服务器发送请求的时候,并将参数保存到数据库时遇到了中文乱码的问题: 解决方法: url = "http://xxxx.com/Orders/saveorder.html ...

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

    先打个小广告哈 公司招java架构师,月薪25K以上,负责电商平台架构工作,工作地点在北京 1号线永安里站 附近,如有意向 请把简历发我邮箱jia6235@163.com 可以内部推荐. DHC是一款 ...

  5. Android - 向服务器发送数据(POST) - HTTPClient.

    该篇文章主要说明使用Apache提供的HTTPClient,通过post方式,向服务器发送数据.由于有些东西在 Android - 向服务器发送数据(GET)中提到过,就不再重复. 一,Android ...

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

    使用post()方法以POST方式从服务器发送数据 与get()方法相比,post()方法多用于以POST方式向服务器发送数据,服务器接收到数据之后,进行处理,并将处理结果返回页面,调用格式如下: $ ...

  7. Android - 向服务器发送数据(GET).

    在此,使用HTTP协议,通过GET请求,向服务器发送请求,这种方式适合于数据量小,数据安全性要求不高的情况下. 一,服务器端,使用Servlet. 在服务器端,定义一个HttpServlet的子类,以 ...

  8. Socket实现单客户端与服务器对话功能

    单客户端,顾名思义,就是客户端只有一个用户去访问服务器,然后服务器根据该客户请求返回信息,先看下效果图: 服务端(左)和客户端(右): 注意,我是用了两个eclipse,一个只放服务端文件,一个只放客 ...

  9. 【实验室笔记】C#的Socket客户端接收和发送数据

    采用socket发送和接收数据的实验中,服务器采用的是网络助手作为模拟服务器端. 客户端程序流程: 应用的命名空间: using System.Net; using System.Net.Socket ...

随机推荐

  1. User_Agent大全

    'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Ver ...

  2. 基于注解的接口限流+统一session认证

    代码心得: 一个基本的做法:对于用户身份认证做到拦截器里,针对HandlerMethod进行统一拦截认证,根据方法上的注解标识,判别是否需要身份验证,并将查找出来的User实体存入ThreadLoca ...

  3. mysql知识积累

    验证mysql工作状态 systemctl status mysql.service 启动 sudo systemctl start mysql 停止 service mysql stop 重启mys ...

  4. MySQL/Oracle视图的创建与使用

    1.什么是视图? 视图是一个虚拟的表,是一个表中的数据经过某种筛选后的显示方式,视图由一个预定义的查询select语句组成.   2.视图的特点. 视图中的数据并不属于视图本身,而是属于基本的表,对视 ...

  5. python3.4对已经存在的excel写入数据

    #!/usr/bin/env python # -*- coding:utf-8 -*- # __author__ = "blzhu" """ pyt ...

  6. hashchange事件

    h5新增了hashchange事件,以便在URL参数列表(及URL中‘#’号后面的所有字符串),发生变化时通知开发人员. 之所以要添加这个事件,是因为在Ajax应用中,开发人员经常要利用URL参数列表 ...

  7. Calendar 得到前一天当前时间

    @Test public void test(){ //因为Calendar的构造方法是私有的,所以实例化一个Calendar对象用getInstance方法 Calendar calendar = ...

  8. RAW转换成RGB

    clc; clear; close all; [filename,pathname]=uigetfile({'*.*','All Files (*.*)'},'Pick a file'); file ...

  9. (转载)Fiddler调式使用知多少(一)深入研究

    原文来源于:http://www.cnblogs.com/tugenhua0707/p/4623317.html,作者:涂根华 !个人觉得原作者写的特别好,故收藏于此 Fiddler调式使用(一)深入 ...

  10. 【转】Javascript基本类型和引用类型的区别

    根据[转贴]进一步补充 今天明白了一个困扰很久的问题:引用类型和基本类型的区别与联系要明白这个问题,首先需要理解堆栈的概念.那什么又是堆栈,有什么区别和联系呢?堆:首先堆是动态分配的,JVM并不会自动 ...