C#-c# 如何使用windows的服务挂起异步socket?

C#-c# 如何使用windows的服务挂起异步socket?

虐人心 发布于 2017-07-26 字数 0 浏览 1364 回复 5

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

偏爱自由 2017-10-20 5 楼

不是很清楚你的意图,Socket暂停执行好像在我印象里没法直接实现,小弟倒是针对的你的问题有两种解决方案,
1、在服务暂停时,直接关闭通讯的socket,恢复时在重新建立Socket
2、引入标志位,来控制Socket的回调函数的执行,在服务暂停时,直接关闭通讯的标志位置未false表示不让Socket进行回调,恢复时恢复标志位。
个人觉得2好一些,这样你原先建立的连接不会被重置,数据链路还是保持通讯,只不过程序在挂起后不去处理Socket的数据而已。
以上是个人愚见,不知可否帮到你

想挽留 2017-08-10 3 楼

判断并发送

 sock.BeginSend(
buffer, 0, size, SocketFlags.None,
new AsyncCallback(EndSendFile),
null);

归属感 2017-07-28 2 楼

这个是接收端也就是服务端的代码。
#define _GNU_SOURCE

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>

#define MAX_LENTH 1500

#define SIG_FIFO_IO SIGRTMIN+1
//这时SIGIO表示实时信号队列已满

static char recv_buf[MAX_LENTH] = {0};

int main(int argc, char *argv[])
{
int sockfd, on = 1;
struct sigaction action;
sigset_t newmask, oldmask;
struct sockaddr_in addr;

memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(50001);
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("Create socket failed");
exit(-1);
}
if (bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
perror("Bind socket failed");
exit(-1);
}

/* memset(&action, 0, sizeof(action));
action.sa_handler = sigio_handler;
action.sa_flags = 0;
sigaction(SIGIO, &action, NULL); */

if (fcntl(sockfd, F_SETOWN, getpid()) == -1) {
perror("Fcntl F_SETOWN failed");
exit(-1);
}
if (fcntl(sockfd, F_SETSIG, SIG_FIFO_IO) == -1) {
perror("Fcntl F_SETSIG failed");
exit(-1);
}
if (ioctl(sockfd, FIOASYNC, &on) == -1) {
perror("Ioctl FIOASYNC failed");
exit(-1);
}

int rcvd_sig, len;
siginfo_t info;
sigemptyset(&newmask);
sigaddset(&newmask, SIG_FIFO_IO);
sigprocmask(SIG_BLOCK, &newmask, &oldmask);

while (1) {
rcvd_sig = sigwaitinfo(&newmask, &info);//siginfo中的_sigpool{si_band, si_fd},其中si_fd为socket的文件描述符值

if (rcvd_sig == -1) {
perror("sigio: sigwaitinfo");
exit(-1);
}
else {
printf("Signal %d, socket fd %d received from socketn",
rcvd_sig, info.si_fd);
len = recv(sockfd, recv_buf, MAX_LENTH, MSG_DONTWAIT);
if( len>0)
puts( recv_buf);
exit(-1);
}
}

}

效率应该比较高,通过siginfo_t的si_fd可以找到相应的socket文件描述符,所以对多个客户端的连接也能处理,如果还配以使用si_band还能知道该信号具体的含义如下:

POLL_IN Data input available.
POLL_OUT Output buffers available.
POLL_MSG Input message available.
POLL_ERR I/O error.
POLL_PRI High priority input available.
POLL_HUP Device disconnected.
这些东西很像poll系统调用中struct pollfd中的revents。
2发送端
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <netinet/in.h> /*socket address struct*/
#include <arpa/inet.h> /*host to network convertion*/
#include <sys/socket.h>
#include <signal.h>
#define MAX_TRANSPORT_LENTH 512

int main()
{
struct sockaddr_in addr;
memset(&addr,0,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
addr.sin_port = htons(50001);

int sock;
sock = socket(AF_INET,SOCK_DGRAM,0);
if(sock == -1)
{
perror("Create socket failed");
exit(-1);
}

int ret;
ret = connect(sock,(struct sockaddr *)&addr,sizeof(addr));
if(ret == -1)
{
perror("Connect socket failed");
exit(-1);
}
while(1)
{
printf("Will send messge to servern");
write(sock,"Some unknown infomationn",MAX_TRANSPORT_LENTH);
sleep(1);
}

}

晚风撩人 2017-07-26 1 楼

命名空间:using System.Net;using System.Net.Socket;

构造新的socket对象:socket原型:

Public socket (AddressFamily addressFamily,SocketType sockettype,ProtocolType protocolType)

AddressFamily 用来指定socket解析地址的寻址方案。InterNetwork标示需要ip版本4的地址,InterNetworkV6需要ip版本6的地址

SocketType参数指定socket类型Raw支持基础传输协议访问,Stream支持可靠,双向,基于连接的数据流。

ProtocolType表示socket支持的网络协议