SOCKET 编程实例

server 端
#include <WINSOCK2.H>
#include <stdio.h> 
#define PORT       6000 //服务器端口 
#define MSGSIZE    1024 //收发缓冲区的大小
#pragma comment(lib, "ws2_32.lib") //链接静态库
 
DWORD WINAPI FunThread(LPVOID); //创建一个线程,专门用来接收数据
 
SOCKET  sClient; //连接所用套节字
 
SOCKET  sListen; //监听套接字
 
SOCKADDR_IN client; //保存客户的地址信息
 
int   iaddrSize = sizeof(SOCKADDR_IN); 
int main()

WSADATA   wsaData;
SOCKADDR_IN local; 
char    s_Message[MSGSIZE];                                        //收发缓冲区 

WSAStartup(0x0202, &wsaData);                                      //Initialize Windows socket library 

/*socket函数用于创建一个套接字*/
sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//创建服务器监听套节字。TCP协议

/* bind函数用于将套接字绑定到一个已知的地址上。如果函数执行成功,返回值为0,否则为SOCKET_ERROR。*****/ 
local.sin_family = AF_INET;                                        //AF_INET指明使用TCP/IP协议族
local.sin_port = htons(PORT);                                      //指明连接服务器的端口号
local.sin_addr.s_addr = htonl(INADDR_ANY);                         //自动获取本机地址
bind(sListen, (struct sockaddr *)&local, sizeof(SOCKADDR_IN));     //地址绑定到套接字

/*listen函数用于将套接字置入监听模式*/ 
listen(sListen, 1);                                                //开始监听
 
/*accpet函数用于接受客户端的连接请求。返回值是一个新的套接字,它对应于已经接受的客户端连接,对于该客户端的所有后续操作,都应使用这个新的套接字*/
sClient = accept(sListen, (struct sockaddr *)&client, &iaddrSize); //建立连接
printf("Accepte client:%s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); 
HANDLE hThread=CreateThread(NULL,0,FunThread,0,0,0);               //创建接收线程
CloseHandle(hThread);                                              //关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等

while (TRUE)

   printf("Server Send:");                                         //从键盘输入 
   gets(s_Message);                                                //发送数据
   /*send函数在已经建立连接的套接字上发送数据。*/
   send(sClient, s_Message, strlen(s_Message), 0);
 

return 0; 
}  

/*程序中专门建立一个FunThread线程用来接收数据,实现双向通信,也可以连续发送、连续接收。*/
DWORD WINAPI FunThread(LPVOID)
{    
char c_Message[MSGSIZE]; //收发缓冲区
int ret; //接收字节的个数
 
while (TRUE)
{   
   /*recv函数用于从连接的套接字中接收数据。*/
   ret = recv(sClient, c_Message, MSGSIZE, 0);                    //接收数据
 
   if(ret==SOCKET_ERROR)
   { 
    printf("\nclient is closed!");
    
    sClient = accept(sListen, (struct sockaddr *)&client, &iaddrSize);//重新开始监听
 
    printf("\nAccepte new client:%s:%d", inet_ntoa(client.sin_addr), ntohs(client.sin_port)); 
    memset(c_Message,0,1024);                                    //将原来的client message归零
    continue;
   } 
   c_Message[ret] = '\0'; 
   printf("\nReceived: %s\n", c_Message); 

return 0;  
}

client端

#include <WINSOCK2.H>
#include <stdio.h> 
#define SERVER_ADDRESS "127.0.0.1" //服务器端IP地址
 
#define PORT           6000         
#define MSGSIZE        1024        
#pragma comment(lib, "ws2_32.lib") 
DWORD WINAPI FunThread(LPVOID);    
SOCKET      sClient;               
SOCKADDR_IN server;
                
int main()
{  
WSADATA     wsaData;  
char        c_Message[MSGSIZE]; 
 
WSAStartup(0x0202, &wsaData);
 
sClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 /* socket函数用于创建一个套接字
    SOCKET socket(int af ,int type,int protocol);
       af:标识一个地址家族,通常为AF_INET。
       type:标识套接字类型,如果为SOCK_STREAM,表示流式套接字;如果为SOCK_DGRAM,表示数据报套接字.
       protocol:标识一个特殊的协议被用于套接字,通常为0,标识采用默认的TCP/IP协议.
 */   
 
memset(&server, 0, sizeof(SOCKADDR_IN));               //先将保存地址的server置为全0
 
server.sin_family = PF_INET;                           //声明地址格式是TCP/IP地址格式
server.sin_port = htons(PORT);                         //指明连接服务器的端口号
server.sin_addr.s_addr = inet_addr(SERVER_ADDRESS);    //指明连接服务器的IP地址
  
connect(sClient, (struct sockaddr *)&server, sizeof(SOCKADDR_IN)); //连到刚才指明的服务器上
/*connect函数*/ 
 
HANDLE hThread=CreateThread(NULL,0,FunThread,0,0,0);
CloseHandle(hThread);
while (TRUE)

   printf("Client Send:");
   gets(c_Message);            
   send(sClient, c_Message, strlen(c_Message), 0);
  
   if(!strcmp(c_Message,"exit"))//server让client退出
   /*strcmp是C语言中头文件(字符串函数)中定义的一个用于对两组字符串进行比较的函数,它的返回值是int类型*/
    exit(1);
}
 
// 释放连接和进行结束工作
closesocket(sClient);
/*每次调用了WSAStartup函数,你都需要调用WSACleanup函数,通知系统来卸载库文件及清除已分配的资源,这个函数十分简单,没有任何参数*/
WSACleanup();

return 0;

 

DWORD WINAPI FunThread(LPVOID)

char   s_Message[MSGSIZE];
int    ret; 
while (TRUE)

   /*recv函数用于从连接的套接字中接收数据。*/
   ret = recv(sClient, s_Message, MSGSIZE, 0);
   if(ret==SOCKET_ERROR)
   { 
    printf("\nServer is closed!\n");
    exit(1);
   } 
   s_Message[ret] = '\0';   
   printf("\nReceived: %s\n", s_Message); 
  
   if(!strcmp(s_Message,"exit"))    //server让client退出
     exit(1);
 /*退出程序 子程序中:退出主函数,主函数中:退出主函数(和return 不同的是子函数中:返回主函数,主函数中:退出主函数)*/

return 0;

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值