C++ Socket实现

转自:https://www.cnblogs.com/chencaiming/p/7249904.html

sockets(套接字)编程有三种,流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM),原始套接字(SOCK_RAW);基于TCP的socket编程是采用的流式套接字。

服务器端编程的步骤:

1:加载套接字库,创建套接字(WSAStartup()/socket());

2:绑定套接字到一个IP地址和一个端口上(bind());

3:将套接字设置为监听模式等待连接请求(listen());

4:请求到来后,接受连接请求,返回一个新的对应于此次连接的套接字(accept());

5:用返回的套接字和客户端进行通信(send()/recv());

6:返回,等待另一连接请求;

7:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。

客户端编程的步骤:

1:加载套接字库,创建套接字(WSAStartup()/socket());

2:向服务器发出连接请求(connect());

3:和服务器端进行通信(send()/recv());

4:关闭套接字,关闭加载的套接字库(closesocket()/WSACleanup())。

第一式: 加载/释放Winsock库:

1.加载方法:

WSADATA wsa;
/初始化socket资源/
if (WSAStartup(MAKEWORD(1,1),&wsa) != 0)
{
return; //代表失败
}

2.释放方法:

WSACleanup();

第二式: 构造SOCKET:

1.服务端:构造监听SOCKET,流式SOCKET.
SOCKET Listen_Sock = socket(AF_INET, SOCK_STREAM, 0)

2.客户端:构造通讯SOCKET,流式SOCKET.
SOCKET Client_Sock = socket(AF_INET, SOCK_STREAM, 0)

第三式:配置监听地址和端口:

1.服务端: SOCKADDR_IN serverAddr
ZeroMemory((char *)&serverAddr,sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_port = htons(1234); /本地监听端口:1234/
serverAddr.sin_addr.s_addr = htonl(INADDR_ANY); /有IP/

第四式: 绑定SOCKET:

1.服务端:绑定监听SOCKET.
bind(Listen_Sock,(struct sockaddr *)&serverAddr,sizeof(serverAddr))

第五式: 服务端/客户端连接:

1.服务端:等待客户端接入.
SOCKET Command_Sock = accept(Listen_Sock, …)

2.客户端:请求与服务端连接.
int ret = connect(Client_Sock, …)

第六式: 收/发数据:

1.服务端:等待客户端接入.char buf[1024].
接收数据:recv(Command_Sock,buf, …)

发送数据:send(Command_Sock,buf, …)

2.客户端:请求与服务端连接.char buf[1024].
发送数据:send(Client_Sock,buf, …)

接收数据:recv(Client_Sock,buf, …)

第七式: 关闭SOCKET:

1.服务端:关闭SOCKET.
closesocket(Listen_Sock)
closesocket(Command_Sock)

2.客户端:关闭SOCKET.
closesocket(Client_Sock)


#include <stdio.h>
#include <Winsock2.h>
void main()
{
 WORD wVersionRequested;
 WSADATA wsaData;
 int err;
  
 wVersionRequested = MAKEWORD( 1, 1 );
  
 err = WSAStartup( wVersionRequested, &wsaData );
 if ( err != 0 ) {
  return;
 }
  
 if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) {
  WSACleanup( );
  return;
 }
 SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
 
 SOCKADDR_IN addrSrv;
 addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
 addrSrv.sin_family=AF_INET;
 addrSrv.sin_port=htons(6000);
  
 bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
 
 listen(sockSrv,5);
 
 SOCKADDR_IN addrClient;
 int len=sizeof(SOCKADDR);
 while(1)
 {
  SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
  char sendBuf[50];
  sprintf(sendBuf,"Welcome %s to here!",inet_ntoa(addrClient.sin_addr));
  send(sockConn,sendBuf,strlen(sendBuf)+1,0);
  char recvBuf[50];
  recv(sockConn,recvBuf,50,0);
  printf("%s\n",recvBuf);
  closesocket(sockConn);
 }
 
}
#include <stdio.h>
#include <Winsock2.h>
void main()
{
 WORD wVersionRequested;
 WSADATA wsaData;
 int err;
 
 wVersionRequested = MAKEWORD( 1, 1 );
 
 err = WSAStartup( wVersionRequested, &wsaData );
 if ( err != 0 ) {
  return;
 }
 
 if ( LOBYTE( wsaData.wVersion ) != 1 ||
        HIBYTE( wsaData.wVersion ) != 1 ) {
  WSACleanup( );
  return;
 }
 SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);
 
 SOCKADDR_IN addrSrv;
 addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
 addrSrv.sin_family=AF_INET;
 addrSrv.sin_port=htons(6000);
 connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
 send(sockClient,"hello",strlen("hello")+1,0);
 char recvBuf[50];
 recv(sockClient,recvBuf,50,0);
 printf("%s\n",recvBuf);
 
 closesocket(sockClient);
 WSACleanup();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用 C socket 实现文件传输的示例代码(请注意代码中的注释): ``` #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #define PORT 8080 #define MAXLINE 1024 int main() { int sockfd; struct sockaddr_in servaddr, cliaddr; // 创建套接字 sockfd = socket(AF_INET, SOCK_DGRAM, 0); memset(&servaddr, 0, sizeof(servaddr)); memset(&cliaddr, 0, sizeof(cliaddr)); // 设置服务端地址信息 servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = INADDR_ANY; servaddr.sin_port = htons(PORT); // 绑定套接字与地址 bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)); int len; char buffer[MAXLINE]; FILE *fp; while (1) { len = sizeof(cliaddr); // 从客户端接收文件名 int n = recvfrom(sockfd, (char *)buffer, MAXLINE, MSG_WAITALL, (struct sockaddr *)&cliaddr, &len); buffer[n] = '\0'; // 以只读二进制方式打开文件 fp = fopen(buffer, "rb"); if (fp == NULL) { printf("File open error.\n"); return 0; } // 从文件读取数据发送客户端 int i, j; char temp[MAXLINE]; bzero(temp, MAXLINE); while ((i = fread(temp, sizeof(char), MAXLINE, fp)) > 0) { if (sendto(sockfd, temp, i, MSG_CONFIRM, (const struct sockaddr *)&cliaddr, len) == -1) { printf("ERROR: Failed to send file.\n"); break; } bzero(temp, MAXLINE); } // 关闭文件 fclose(fp); printf("File sent successfully.\n"); } return 0; } ``` 希望能够解决你的问题!接下来请问需要我回答什么?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值